aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-service-transport_neighbours.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/gnunet-service-transport_neighbours.c')
-rw-r--r--src/transport/gnunet-service-transport_neighbours.c908
1 files changed, 459 insertions, 449 deletions
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c
index bd9257db3..ca4fa7824 100644
--- a/src/transport/gnunet-service-transport_neighbours.c
+++ b/src/transport/gnunet-service-transport_neighbours.c
@@ -38,7 +38,6 @@
38#include "transport.h" 38#include "transport.h"
39 39
40 40
41
42/** 41/**
43 * Size of the neighbour hash map. 42 * Size of the neighbour hash map.
44 */ 43 */
@@ -509,11 +508,14 @@ static unsigned long long bytes_in_send_queue;
509/** 508/**
510 * Task transmitting utilization data 509 * Task transmitting utilization data
511 */ 510 */
512static struct GNUNET_SCHEDULER_Task * util_transmission_tk; 511static struct GNUNET_SCHEDULER_Task *util_transmission_tk;
513 512
514 513
515/** 514/**
516 * FIXME 515 * Convert the given ACK state to a string.
516 *
517 * @param s state
518 * @return corresponding human-readable string
517 */ 519 */
518static char * 520static char *
519print_ack_state (enum GST_ACK_State s) 521print_ack_state (enum GST_ACK_State s)
@@ -617,7 +619,6 @@ neighbours_changed_notification (const struct GNUNET_PeerIdentity *peer,
617} 619}
618 620
619 621
620
621/** 622/**
622 * Lookup a neighbour entry in the neighbours hash map. 623 * Lookup a neighbour entry in the neighbours hash map.
623 * 624 *
@@ -662,7 +663,8 @@ send_outbound_quota (const struct GNUNET_PeerIdentity *target,
662 663
663 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 664 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
664 "Sending outbound quota of %u Bps for peer `%s' to all clients\n", 665 "Sending outbound quota of %u Bps for peer `%s' to all clients\n",
665 ntohl (quota.value__), GNUNET_i2s (target)); 666 ntohl (quota.value__),
667 GNUNET_i2s (target));
666 q_msg.header.size = htons (sizeof (struct QuotaSetMessage)); 668 q_msg.header.size = htons (sizeof (struct QuotaSetMessage));
667 q_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA); 669 q_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SET_QUOTA);
668 q_msg.quota = quota; 670 q_msg.quota = quota;
@@ -682,49 +684,34 @@ static void
682free_address (struct NeighbourAddress *na) 684free_address (struct NeighbourAddress *na)
683{ 685{
684 if (GNUNET_YES == na->ats_active) 686 if (GNUNET_YES == na->ats_active)
685 {
686 GST_validation_set_address_use (na->address, 687 GST_validation_set_address_use (na->address,
687 GNUNET_NO); 688 GNUNET_NO);
688 GST_ats_set_in_use (na->address,
689 na->session,
690 GNUNET_NO);
691 }
692
693 na->bandwidth_in = GNUNET_BANDWIDTH_value_init (0);
694 na->bandwidth_out = GNUNET_BANDWIDTH_value_init (0);
695 na->ats_active = GNUNET_NO;
696 na->keep_alive_nonce = 0;
697 if (NULL != na->address) 689 if (NULL != na->address)
698 { 690 {
691 GST_ats_block_address (na->address,
692 na->session);
699 GNUNET_HELLO_address_free (na->address); 693 GNUNET_HELLO_address_free (na->address);
700 na->address = NULL; 694 na->address = NULL;
701 } 695 }
696 na->bandwidth_in = GNUNET_BANDWIDTH_value_init (0);
697 na->bandwidth_out = GNUNET_BANDWIDTH_value_init (0);
698 na->ats_active = GNUNET_NO;
699 na->keep_alive_nonce = 0;
702 na->session = NULL; 700 na->session = NULL;
703} 701}
704 702
705 703
706/** 704/**
707 * Set net state for this neighbour and notify monitoring 705 * Master task run for every neighbour. Performs all of the time-related
706 * activities (keep alive, send next message, disconnect if idle, finish
707 * clean up after disconnect).
708 * 708 *
709 * @param n the respective neighbour 709 * @param cls the `struct NeighbourMapEntry` for which we are running
710 * @param s the new state 710 * @param tc scheduler context (unused)
711 */ 711 */
712static void 712static void
713set_state (struct NeighbourMapEntry *n, 713master_task (void *cls,
714 enum GNUNET_TRANSPORT_PeerState s) 714 const struct GNUNET_SCHEDULER_TaskContext *tc);
715{
716 n->state = s;
717 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
718 "Neighbour `%s' changed state to %s\n",
719 GNUNET_i2s (&n->id),
720 GNUNET_TRANSPORT_ps2s(s));
721 neighbours_changed_notification (&n->id,
722 n->primary_address.address,
723 n->state,
724 n->timeout,
725 n->primary_address.bandwidth_in,
726 n->primary_address.bandwidth_out);
727}
728 715
729 716
730/** 717/**
@@ -739,7 +726,36 @@ set_state_and_timeout (struct NeighbourMapEntry *n,
739 enum GNUNET_TRANSPORT_PeerState s, 726 enum GNUNET_TRANSPORT_PeerState s,
740 struct GNUNET_TIME_Absolute timeout) 727 struct GNUNET_TIME_Absolute timeout)
741{ 728{
729 if (GNUNET_TRANSPORT_is_connected (s) &&
730 ! GNUNET_TRANSPORT_is_connected (n->state) )
731 {
732 neighbours_connect_notification (&n->id,
733 n->primary_address.bandwidth_in,
734 n->primary_address.bandwidth_out);
735 GNUNET_STATISTICS_set (GST_stats,
736 gettext_noop ("# peers connected"),
737 ++neighbours_connected,
738 GNUNET_NO);
739 }
740 if (! GNUNET_TRANSPORT_is_connected (s) &&
741 GNUNET_TRANSPORT_is_connected (n->state) )
742 {
743 GNUNET_STATISTICS_set (GST_stats,
744 gettext_noop ("# peers connected"),
745 --neighbours_connected,
746 GNUNET_NO);
747 neighbours_disconnect_notification (&n->id);
748 }
742 n->state = s; 749 n->state = s;
750 if ( (timeout.abs_value_us < n->timeout.abs_value_us) &&
751 (NULL != n->task ) )
752 {
753 /* new timeout is earlier, reschedule master task */
754 GNUNET_SCHEDULER_cancel (n->task);
755 n->task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining (timeout),
756 &master_task,
757 n);
758 }
743 n->timeout = timeout; 759 n->timeout = timeout;
744 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 760 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
745 "Neighbour `%s' changed state to %s with timeout %s\n", 761 "Neighbour `%s' changed state to %s with timeout %s\n",
@@ -756,29 +772,6 @@ set_state_and_timeout (struct NeighbourMapEntry *n,
756 772
757 773
758/** 774/**
759 * Set new state timeout for this neighbour and notify monitoring
760 *
761 * @param n the respective neighbour
762 * @param timeout the new timeout
763 */
764static void
765set_timeout (struct NeighbourMapEntry *n,
766 struct GNUNET_TIME_Absolute timeout)
767{
768 n->timeout = timeout;
769 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
770 "Neighbour `%s' changed timeout %s\n",
771 GNUNET_i2s (&n->id),
772 GNUNET_STRINGS_absolute_time_to_string (timeout));
773 neighbours_changed_notification (&n->id,
774 n->primary_address.address,
775 n->state, n->timeout,
776 n->primary_address.bandwidth_in,
777 n->primary_address.bandwidth_out);
778}
779
780
781/**
782 * Initialize the alternative address of a neighbour 775 * Initialize the alternative address of a neighbour
783 * 776 *
784 * @param n the neighbour 777 * @param n the neighbour
@@ -809,9 +802,15 @@ set_alternative_address (struct NeighbourMapEntry *n,
809 n->alternative_address.bandwidth_out = bandwidth_out; 802 n->alternative_address.bandwidth_out = bandwidth_out;
810 return; 803 return;
811 } 804 }
812 free_address (&n->alternative_address); 805 if (NULL != n->alternative_address.address)
806 {
807 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
808 "Replacing existing alternative address with another one\n");
809 free_address (&n->alternative_address);
810 }
813 if (NULL == session) 811 if (NULL == session)
814 session = papi->get_session (papi->cls, address); 812 session = papi->get_session (papi->cls,
813 address);
815 if (NULL == session) 814 if (NULL == session)
816 { 815 {
817 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 816 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -824,7 +823,8 @@ set_alternative_address (struct NeighbourMapEntry *n,
824 GNUNET_NO); 823 GNUNET_NO);
825 return; 824 return;
826 } 825 }
827 GST_ats_new_session (address, session); 826 GST_ats_new_session (address,
827 session);
828 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 828 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
829 "Neighbour `%s' configured alternative address %s\n", 829 "Neighbour `%s' configured alternative address %s\n",
830 GNUNET_i2s (&n->id), 830 GNUNET_i2s (&n->id),
@@ -859,48 +859,50 @@ set_primary_address (struct NeighbourMapEntry *n,
859 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, 859 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
860 int is_active) 860 int is_active)
861{ 861{
862 struct GNUNET_TRANSPORT_PluginFunctions *papi;
863
864 if (NULL == (papi = GST_plugins_find (address->transport_name)))
865 {
866 GNUNET_break (0);
867 return;
868 }
869 if (session == n->primary_address.session) 862 if (session == n->primary_address.session)
870 { 863 {
871 n->primary_address.bandwidth_in = bandwidth_in;
872 n->primary_address.bandwidth_out = bandwidth_out;
873 if (is_active != n->primary_address.ats_active) 864 if (is_active != n->primary_address.ats_active)
874 { 865 {
875 n->primary_address.ats_active = is_active; 866 n->primary_address.ats_active = is_active;
876 GST_ats_set_in_use (n->primary_address.address,
877 n->primary_address.session,
878 is_active);
879 GST_validation_set_address_use (n->primary_address.address, 867 GST_validation_set_address_use (n->primary_address.address,
880 is_active); 868 is_active);
881 } 869 }
882 if (GNUNET_YES == is_active) 870 if (GNUNET_YES == is_active)
883 { 871 {
884 GST_neighbours_set_incoming_quota (&address->peer, bandwidth_in); 872 if (n->primary_address.bandwidth_in.value__ != bandwidth_in.value__)
885 send_outbound_quota (&address->peer, bandwidth_out); 873 {
874 n->primary_address.bandwidth_in = bandwidth_in;
875 GST_neighbours_set_incoming_quota (&address->peer, bandwidth_in);
876 }
877 if (n->primary_address.bandwidth_out.value__ != bandwidth_out.value__)
878 {
879 n->primary_address.bandwidth_out = bandwidth_out;
880 send_outbound_quota (&address->peer,
881 bandwidth_out);
882 }
886 } 883 }
887 return; 884 return;
888 } 885 }
889 free_address (&n->primary_address); 886 if ( (NULL != n->primary_address.address) &&
890 if (NULL == session) 887 (0 == GNUNET_HELLO_address_cmp (address,
891 session = papi->get_session (papi->cls, address); 888 n->primary_address.address)) )
889 {
890 GNUNET_break (0);
891 return;
892 }
892 if (NULL == session) 893 if (NULL == session)
893 { 894 {
894 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 895 GNUNET_break (0);
895 "Failed to obtain new session for peer `%s' and address '%s'\n", 896 GST_ats_block_address (address,
896 GNUNET_i2s (&address->peer), GST_plugins_a2s (address)); 897 session);
897 GNUNET_STATISTICS_update (GST_stats,
898 gettext_noop ("# session creation failed"),
899 1,
900 GNUNET_NO);
901 return; 898 return;
902 } 899 }
903 GST_ats_new_session (address, session); 900 if (NULL != n->primary_address.address)
901 {
902 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
903 "Replacing existing primary address with another one\n");
904 free_address (&n->primary_address);
905 }
904 n->primary_address.address = GNUNET_HELLO_address_copy (address); 906 n->primary_address.address = GNUNET_HELLO_address_copy (address);
905 n->primary_address.bandwidth_in = bandwidth_in; 907 n->primary_address.bandwidth_in = bandwidth_in;
906 n->primary_address.bandwidth_out = bandwidth_out; 908 n->primary_address.bandwidth_out = bandwidth_out;
@@ -909,14 +911,12 @@ set_primary_address (struct NeighbourMapEntry *n,
909 n->primary_address.keep_alive_nonce = 0; 911 n->primary_address.keep_alive_nonce = 0;
910 if (GNUNET_YES == is_active) 912 if (GNUNET_YES == is_active)
911 { 913 {
912 /* Telling ATS about new session */ 914 /* subsystems about address use */
913 GST_ats_set_in_use (n->primary_address.address,
914 n->primary_address.session,
915 GNUNET_YES);
916 GST_validation_set_address_use (n->primary_address.address, 915 GST_validation_set_address_use (n->primary_address.address,
917 GNUNET_YES); 916 GNUNET_YES);
918 GST_neighbours_set_incoming_quota (&address->peer, bandwidth_in); 917 GST_neighbours_set_incoming_quota (&address->peer, bandwidth_in);
919 send_outbound_quota (&address->peer, bandwidth_out); 918 send_outbound_quota (&address->peer,
919 bandwidth_out);
920 } 920 }
921 921
922 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 922 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -943,32 +943,21 @@ static void
943unset_primary_address (struct NeighbourMapEntry *n) 943unset_primary_address (struct NeighbourMapEntry *n)
944{ 944{
945 /* Notify monitoring about change */ 945 /* Notify monitoring about change */
946 if (NULL == n->primary_address.address)
947 return;
948 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
949 "Disabling primary address\n");
946 neighbours_changed_notification (&n->id, 950 neighbours_changed_notification (&n->id,
947 n->primary_address.address, 951 n->primary_address.address,
948 n->state, 952 n->state,
949 n->timeout, 953 n->timeout,
950 GNUNET_BANDWIDTH_value_init (0), 954 GNUNET_BANDWIDTH_value_init (0),
951 GNUNET_BANDWIDTH_value_init (0)); 955 GNUNET_BANDWIDTH_value_init (0));
952 /* Unset primary address */
953 free_address (&n->primary_address); 956 free_address (&n->primary_address);
954} 957}
955 958
956 959
957/** 960/**
958 * Clear the alternative address of a neighbour since this address is not
959 * valid anymore
960 *
961 * @param n the neighbour
962 */
963static void
964unset_alternative_address (struct NeighbourMapEntry *n)
965{
966 /* Unset primary address */
967 free_address (&n->alternative_address);
968}
969
970
971/**
972 * Free a neighbour map entry. 961 * Free a neighbour map entry.
973 * 962 *
974 * @param n entry to free 963 * @param n entry to free
@@ -986,29 +975,29 @@ free_neighbour (struct NeighbourMapEntry *n)
986 /* fail messages currently in the queue */ 975 /* fail messages currently in the queue */
987 while (NULL != (mq = n->messages_head)) 976 while (NULL != (mq = n->messages_head))
988 { 977 {
989 GNUNET_CONTAINER_DLL_remove (n->messages_head, n->messages_tail, mq); 978 GNUNET_CONTAINER_DLL_remove (n->messages_head,
979 n->messages_tail,
980 mq);
990 if (NULL != mq->cont) 981 if (NULL != mq->cont)
991 mq->cont (mq->cont_cls, GNUNET_SYSERR, mq->message_buf_size, 0); 982 mq->cont (mq->cont_cls,
983 GNUNET_SYSERR,
984 mq->message_buf_size,
985 0);
992 GNUNET_free (mq); 986 GNUNET_free (mq);
993 } 987 }
994 /* It is too late to send other peer disconnect notifications, but at
995 least internally we need to get clean... */
996 if (GNUNET_YES == test_connected (n))
997 {
998 GNUNET_STATISTICS_set (GST_stats,
999 gettext_noop ("# peers connected"),
1000 --neighbours_connected,
1001 GNUNET_NO);
1002 neighbours_disconnect_notification (&n->id);
1003 }
1004
1005 /* Mark peer as disconnected */ 988 /* Mark peer as disconnected */
1006 set_state (n, GNUNET_TRANSPORT_PS_DISCONNECT_FINISHED); 989 set_state_and_timeout (n,
1007 990 GNUNET_TRANSPORT_PS_DISCONNECT_FINISHED,
991 GNUNET_TIME_UNIT_FOREVER_ABS);
1008 /* free addresses and mark as unused */ 992 /* free addresses and mark as unused */
1009 unset_primary_address (n); 993 unset_primary_address (n);
1010 free_address (&n->alternative_address);
1011 994
995 if (NULL != n->alternative_address.address)
996 {
997 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
998 "Cleaning up alternative address\n");
999 free_address (&n->alternative_address);
1000 }
1012 GNUNET_assert (GNUNET_YES == 1001 GNUNET_assert (GNUNET_YES ==
1013 GNUNET_CONTAINER_multipeermap_remove (neighbours, 1002 GNUNET_CONTAINER_multipeermap_remove (neighbours,
1014 &n->id, n)); 1003 &n->id, n));
@@ -1056,7 +1045,8 @@ free_neighbour (struct NeighbourMapEntry *n)
1056 */ 1045 */
1057static struct GNUNET_TIME_Relative 1046static struct GNUNET_TIME_Relative
1058send_with_session (struct NeighbourMapEntry *n, 1047send_with_session (struct NeighbourMapEntry *n,
1059 const char *msgbuf, size_t msgbuf_size, 1048 const void *msgbuf,
1049 size_t msgbuf_size,
1060 uint32_t priority, 1050 uint32_t priority,
1061 struct GNUNET_TIME_Relative timeout, 1051 struct GNUNET_TIME_Relative timeout,
1062 unsigned int use_keepalive_timeout, 1052 unsigned int use_keepalive_timeout,
@@ -1070,14 +1060,20 @@ send_with_session (struct NeighbourMapEntry *n,
1070 if ( ((NULL == (papi = GST_plugins_find (n->primary_address.address->transport_name)) || 1060 if ( ((NULL == (papi = GST_plugins_find (n->primary_address.address->transport_name)) ||
1071 (-1 == papi->send (papi->cls, 1061 (-1 == papi->send (papi->cls,
1072 n->primary_address.session, 1062 n->primary_address.session,
1073 msgbuf, msgbuf_size, 1063 msgbuf,
1064 msgbuf_size,
1074 priority, 1065 priority,
1075 (result = (GNUNET_NO == use_keepalive_timeout) ? timeout : 1066 (result = (GNUNET_NO == use_keepalive_timeout) ? timeout :
1076 GNUNET_TIME_relative_divide (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 1067 GNUNET_TIME_relative_divide (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
1077 papi->query_keepalive_factor (papi->cls))), 1068 papi->query_keepalive_factor (papi->cls))),
1078 cont, cont_cls)))) && 1069 cont,
1070 cont_cls)))) &&
1079 (NULL != cont)) 1071 (NULL != cont))
1080 cont (cont_cls, &n->id, GNUNET_SYSERR, msgbuf_size, 0); 1072 cont (cont_cls,
1073 &n->id,
1074 GNUNET_SYSERR,
1075 msgbuf_size,
1076 0);
1081 GST_neighbours_notify_data_sent (n->primary_address.address, 1077 GST_neighbours_notify_data_sent (n->primary_address.address,
1082 n->primary_address.session, 1078 n->primary_address.session,
1083 msgbuf_size); 1079 msgbuf_size);
@@ -1087,19 +1083,6 @@ send_with_session (struct NeighbourMapEntry *n,
1087 1083
1088 1084
1089/** 1085/**
1090 * Master task run for every neighbour. Performs all of the time-related
1091 * activities (keep alive, send next message, disconnect if idle, finish
1092 * clean up after disconnect).
1093 *
1094 * @param cls the `struct NeighbourMapEntry` for which we are running
1095 * @param tc scheduler context (unused)
1096 */
1097static void
1098master_task (void *cls,
1099 const struct GNUNET_SCHEDULER_TaskContext *tc);
1100
1101
1102/**
1103 * Function called when the 'DISCONNECT' message has been sent by the 1086 * Function called when the 'DISCONNECT' message has been sent by the
1104 * plugin. Frees the neighbour --- if the entry still exists. 1087 * plugin. Frees the neighbour --- if the entry still exists.
1105 * 1088 *
@@ -1107,11 +1090,14 @@ master_task (void *cls,
1107 * @param target identity of the neighbour that was disconnected 1090 * @param target identity of the neighbour that was disconnected
1108 * @param result #GNUNET_OK if the disconnect got out successfully 1091 * @param result #GNUNET_OK if the disconnect got out successfully
1109 * @param payload bytes payload 1092 * @param payload bytes payload
1110 * @param physical bytes physical 1093 * @param physical bytes on wire
1111 */ 1094 */
1112static void 1095static void
1113send_disconnect_cont (void *cls, const struct GNUNET_PeerIdentity *target, 1096send_disconnect_cont (void *cls,
1114 int result, size_t payload, size_t physical) 1097 const struct GNUNET_PeerIdentity *target,
1098 int result,
1099 size_t payload,
1100 size_t physical)
1115{ 1101{
1116 struct NeighbourMapEntry *n; 1102 struct NeighbourMapEntry *n;
1117 1103
@@ -1157,12 +1143,17 @@ send_disconnect (struct NeighbourMapEntry *n)
1157 &disconnect_msg.purpose, 1143 &disconnect_msg.purpose,
1158 &disconnect_msg.signature)); 1144 &disconnect_msg.signature));
1159 1145
1160 (void) send_with_session (n, (const char *) &disconnect_msg, 1146 (void) send_with_session (n,
1161 sizeof (disconnect_msg), UINT32_MAX, GNUNET_TIME_UNIT_FOREVER_REL, 1147 &disconnect_msg,
1162 GNUNET_NO, &send_disconnect_cont, NULL ); 1148 sizeof (disconnect_msg),
1149 UINT32_MAX,
1150 GNUNET_TIME_UNIT_FOREVER_REL,
1151 GNUNET_NO,
1152 &send_disconnect_cont,
1153 NULL);
1163 GNUNET_STATISTICS_update (GST_stats, 1154 GNUNET_STATISTICS_update (GST_stats,
1164 gettext_noop 1155 gettext_noop ("# DISCONNECT messages sent"),
1165 ("# DISCONNECT messages sent"), 1, 1156 1,
1166 GNUNET_NO); 1157 GNUNET_NO);
1167} 1158}
1168 1159
@@ -1190,7 +1181,9 @@ disconnect_neighbour (struct NeighbourMapEntry *n)
1190 return; 1181 return;
1191 case GNUNET_TRANSPORT_PS_SYN_SENT: 1182 case GNUNET_TRANSPORT_PS_SYN_SENT:
1192 send_disconnect (n); 1183 send_disconnect (n);
1193 set_state (n, GNUNET_TRANSPORT_PS_DISCONNECT); 1184 set_state_and_timeout (n,
1185 GNUNET_TRANSPORT_PS_DISCONNECT,
1186 GNUNET_TIME_UNIT_FOREVER_ABS);
1194 break; 1187 break;
1195 case GNUNET_TRANSPORT_PS_SYN_RECV_ATS: 1188 case GNUNET_TRANSPORT_PS_SYN_RECV_ATS:
1196 /* we never ACK'ed the other peer's request, no need to send DISCONNECT */ 1189 /* we never ACK'ed the other peer's request, no need to send DISCONNECT */
@@ -1199,7 +1192,9 @@ disconnect_neighbour (struct NeighbourMapEntry *n)
1199 case GNUNET_TRANSPORT_PS_SYN_RECV_ACK: 1192 case GNUNET_TRANSPORT_PS_SYN_RECV_ACK:
1200 /* we DID ACK the other peer's request, must send DISCONNECT */ 1193 /* we DID ACK the other peer's request, must send DISCONNECT */
1201 send_disconnect (n); 1194 send_disconnect (n);
1202 set_state (n, GNUNET_TRANSPORT_PS_DISCONNECT); 1195 set_state_and_timeout (n,
1196 GNUNET_TRANSPORT_PS_DISCONNECT,
1197 GNUNET_TIME_UNIT_FOREVER_ABS);
1203 break; 1198 break;
1204 case GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT: 1199 case GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT:
1205 case GNUNET_TRANSPORT_PS_CONNECTED: 1200 case GNUNET_TRANSPORT_PS_CONNECTED:
@@ -1207,12 +1202,9 @@ disconnect_neighbour (struct NeighbourMapEntry *n)
1207 /* we are currently connected, need to send disconnect and do 1202 /* we are currently connected, need to send disconnect and do
1208 internal notifications and update statistics */ 1203 internal notifications and update statistics */
1209 send_disconnect (n); 1204 send_disconnect (n);
1210 GNUNET_STATISTICS_set (GST_stats, 1205 set_state_and_timeout (n,
1211 gettext_noop ("# peers connected"), 1206 GNUNET_TRANSPORT_PS_DISCONNECT,
1212 --neighbours_connected, 1207 GNUNET_TIME_UNIT_FOREVER_ABS);
1213 GNUNET_NO);
1214 neighbours_disconnect_notification (&n->id);
1215 set_state (n, GNUNET_TRANSPORT_PS_DISCONNECT);
1216 break; 1208 break;
1217 case GNUNET_TRANSPORT_PS_RECONNECT_ATS: 1209 case GNUNET_TRANSPORT_PS_RECONNECT_ATS:
1218 /* Disconnecting while waiting for an ATS address to reconnect, 1210 /* Disconnecting while waiting for an ATS address to reconnect,
@@ -1237,7 +1229,8 @@ disconnect_neighbour (struct NeighbourMapEntry *n)
1237 if (NULL != n->task) 1229 if (NULL != n->task)
1238 GNUNET_SCHEDULER_cancel (n->task); 1230 GNUNET_SCHEDULER_cancel (n->task);
1239 n->task = GNUNET_SCHEDULER_add_delayed (DISCONNECT_SENT_TIMEOUT, 1231 n->task = GNUNET_SCHEDULER_add_delayed (DISCONNECT_SENT_TIMEOUT,
1240 &master_task, n); 1232 &master_task,
1233 n);
1241} 1234}
1242 1235
1243 1236
@@ -1276,9 +1269,11 @@ transmit_send_continuation (void *cls,
1276 { 1269 {
1277 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1270 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1278 "Bytes_in_send_queue `%u', Message_size %u, result: %s, payload %u, on wire %u\n", 1271 "Bytes_in_send_queue `%u', Message_size %u, result: %s, payload %u, on wire %u\n",
1279 bytes_in_send_queue, mq->message_buf_size, 1272 bytes_in_send_queue,
1273 mq->message_buf_size,
1280 (GNUNET_OK == success) ? "OK" : "FAIL", 1274 (GNUNET_OK == success) ? "OK" : "FAIL",
1281 size_payload, physical); 1275 size_payload,
1276 physical);
1282 GNUNET_break (0); 1277 GNUNET_break (0);
1283 } 1278 }
1284 1279
@@ -1357,28 +1352,35 @@ try_transmission_to_peer (struct NeighbourMapEntry *n)
1357 gettext_noop 1352 gettext_noop
1358 ("# messages timed out while in transport queue"), 1353 ("# messages timed out while in transport queue"),
1359 1, GNUNET_NO); 1354 1, GNUNET_NO);
1360 GNUNET_CONTAINER_DLL_remove (n->messages_head, n->messages_tail, mq); 1355 GNUNET_CONTAINER_DLL_remove (n->messages_head,
1356 n->messages_tail,
1357 mq);
1361 n->is_active = mq; 1358 n->is_active = mq;
1362 transmit_send_continuation (mq, &n->id, 1359 transmit_send_continuation (mq,
1360 &n->id,
1363 GNUNET_SYSERR, 1361 GNUNET_SYSERR,
1364 mq->message_buf_size, 0); /* timeout */ 1362 mq->message_buf_size,
1363 0); /* timeout */
1365 } 1364 }
1366 if (NULL == mq) 1365 if (NULL == mq)
1367 return; /* no more messages */ 1366 return; /* no more messages */
1368 GNUNET_CONTAINER_DLL_remove (n->messages_head, n->messages_tail, mq); 1367 GNUNET_CONTAINER_DLL_remove (n->messages_head,
1368 n->messages_tail,
1369 mq);
1369 n->is_active = mq; 1370 n->is_active = mq;
1370 1371
1371 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1372 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1372 "Giving message with %u bytes to plugin session %p\n", 1373 "Giving message with %u bytes to plugin session %p\n",
1373 mq->message_buf_size, n->primary_address.session); 1374 mq->message_buf_size,
1374 1375 n->primary_address.session);
1375 (void) send_with_session (n, 1376 (void) send_with_session (n,
1376 mq->message_buf, 1377 mq->message_buf,
1377 mq->message_buf_size, 1378 mq->message_buf_size,
1378 0 /* priority */, 1379 0 /* priority */,
1379 timeout, 1380 timeout,
1380 GNUNET_NO, 1381 GNUNET_NO,
1381 &transmit_send_continuation, mq); 1382 &transmit_send_continuation,
1383 mq);
1382} 1384}
1383 1385
1384 1386
@@ -1398,7 +1400,7 @@ send_keepalive (struct NeighbourMapEntry *n)
1398 uint32_t nonce; 1400 uint32_t nonce;
1399 1401
1400 GNUNET_assert ((GNUNET_TRANSPORT_PS_CONNECTED == n->state) || 1402 GNUNET_assert ((GNUNET_TRANSPORT_PS_CONNECTED == n->state) ||
1401 (GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT)); 1403 (GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT == n->state));
1402 if (GNUNET_TIME_absolute_get_remaining (n->keep_alive_time).rel_value_us > 0) 1404 if (GNUNET_TIME_absolute_get_remaining (n->keep_alive_time).rel_value_us > 0)
1403 return; /* no keepalive needed at this time */ 1405 return; /* no keepalive needed at this time */
1404 1406
@@ -1407,25 +1409,28 @@ send_keepalive (struct NeighbourMapEntry *n)
1407 nonce = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX); 1409 nonce = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
1408 1410
1409 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1411 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1410 "Sending keep alive to peer `%s' with nonce %u\n", 1412 "Sending keep alive to peer `%s' with nonce %u\n",
1411 GNUNET_i2s (&n->id), nonce); 1413 GNUNET_i2s (&n->id),
1412 1414 nonce);
1413 m.header.size = htons (sizeof (struct SessionKeepAliveMessage)); 1415 m.header.size = htons (sizeof (struct SessionKeepAliveMessage));
1414 m.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE); 1416 m.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE);
1415 m.nonce = htonl (nonce); 1417 m.nonce = htonl (nonce);
1416 1418
1417 timeout = send_with_session (n, 1419 timeout = send_with_session (n,
1418 (const void *) &m, sizeof (m), 1420 &m,
1421 sizeof (m),
1419 UINT32_MAX /* priority */, 1422 UINT32_MAX /* priority */,
1420 GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, 1423 GNUNET_TIME_UNIT_FOREVER_REL,
1424 GNUNET_YES,
1421 NULL, NULL); 1425 NULL, NULL);
1422 GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# keepalives sent"), 1, 1426 GNUNET_STATISTICS_update (GST_stats,
1427 gettext_noop ("# keepalives sent"),
1428 1,
1423 GNUNET_NO); 1429 GNUNET_NO);
1424 n->primary_address.keep_alive_nonce = nonce; 1430 n->primary_address.keep_alive_nonce = nonce;
1425 n->expect_latency_response = GNUNET_YES; 1431 n->expect_latency_response = GNUNET_YES;
1426 n->last_keep_alive_time = GNUNET_TIME_absolute_get (); 1432 n->last_keep_alive_time = GNUNET_TIME_absolute_get ();
1427 n->keep_alive_time = GNUNET_TIME_relative_to_absolute (timeout); 1433 n->keep_alive_time = GNUNET_TIME_relative_to_absolute (timeout);
1428
1429} 1434}
1430 1435
1431 1436
@@ -1473,11 +1478,13 @@ GST_neighbours_keepalive (const struct GNUNET_PeerIdentity *neighbour,
1473 msg.header.size = htons (sizeof (struct SessionKeepAliveMessage)); 1478 msg.header.size = htons (sizeof (struct SessionKeepAliveMessage));
1474 msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE_RESPONSE); 1479 msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE_RESPONSE);
1475 msg.nonce = msg_in->nonce; 1480 msg.nonce = msg_in->nonce;
1476 (void) send_with_session(n, 1481 (void) send_with_session (n,
1477 (const void *) &msg, sizeof (struct SessionKeepAliveMessage), 1482 &msg,
1478 UINT32_MAX /* priority */, 1483 sizeof (struct SessionKeepAliveMessage),
1479 GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, 1484 UINT32_MAX /* priority */,
1480 NULL, NULL); 1485 GNUNET_TIME_UNIT_FOREVER_REL,
1486 GNUNET_YES,
1487 NULL, NULL);
1481} 1488}
1482 1489
1483 1490
@@ -1559,7 +1566,9 @@ GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour,
1559 1566
1560 n->primary_address.keep_alive_nonce = 0; 1567 n->primary_address.keep_alive_nonce = 0;
1561 n->expect_latency_response = GNUNET_NO; 1568 n->expect_latency_response = GNUNET_NO;
1562 set_timeout (n, GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT)); 1569 set_state_and_timeout (n,
1570 n->state,
1571 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
1563 1572
1564 latency = GNUNET_TIME_absolute_get_duration (n->last_keep_alive_time); 1573 latency = GNUNET_TIME_absolute_get_duration (n->last_keep_alive_time);
1565 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1574 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1653,9 +1662,8 @@ GST_neighbours_calculate_receive_delay (const struct GNUNET_PeerIdentity
1653 if (ret.rel_value_us > 0) 1662 if (ret.rel_value_us > 0)
1654 { 1663 {
1655 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1664 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1656 "Throttling read (%llu bytes excess at %u b/s), waiting %s before reading more.\n", 1665 "Throttling read (%lld bytes excess at %u b/s), waiting %s before reading more.\n",
1657 (unsigned long long) n->in_tracker. 1666 (long long) n->in_tracker.consumption_since_last_update__,
1658 consumption_since_last_update__,
1659 (unsigned int) n->in_tracker.available_bytes_per_s__, 1667 (unsigned int) n->in_tracker.available_bytes_per_s__,
1660 GNUNET_STRINGS_relative_time_to_string (ret, GNUNET_YES)); 1668 GNUNET_STRINGS_relative_time_to_string (ret, GNUNET_YES));
1661 GNUNET_STATISTICS_update (GST_stats, 1669 GNUNET_STATISTICS_update (GST_stats,
@@ -1728,14 +1736,23 @@ GST_neighbours_send (const struct GNUNET_PeerIdentity *target,
1728 1736
1729 1737
1730/** 1738/**
1731 * FIXME 1739 * Continuation called from our attempt to transmitted our
1740 * #GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_SYN to the specified @a
1741 * target. Continue processing based on the @a result. Specifically,
1742 * if we failed to transmit, discard the address we used.
1743 *
1744 * @param cls NULL
1745 * @param target which peer received the transmission
1746 * @param result #GNUNET_OK if sending worked
1747 * @param size_payload how many bytes of payload were sent (ignored)
1748 * @param size_on_wire how much bandwidth was consumed on the wire (ignored)
1732 */ 1749 */
1733static void 1750static void
1734send_session_connect_cont (void *cls, 1751send_session_syn_cont (void *cls,
1735 const struct GNUNET_PeerIdentity *target, 1752 const struct GNUNET_PeerIdentity *target,
1736 int result, 1753 int result,
1737 size_t size_payload, 1754 size_t size_payload,
1738 size_t size_on_wire) 1755 size_t size_on_wire)
1739{ 1756{
1740 struct NeighbourMapEntry *n; 1757 struct NeighbourMapEntry *n;
1741 1758
@@ -1761,31 +1778,35 @@ send_session_connect_cont (void *cls,
1761 return; 1778 return;
1762 1779
1763 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1780 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1764 _("Failed to send SYN message to peer `%s' using address `%s' session %p\n"), 1781 _("Failed to send SYN message to peer `%s'\n"),
1765 GNUNET_i2s (target), 1782 GNUNET_i2s (target));
1766 GST_plugins_a2s (n->primary_address.address),
1767 n->primary_address.session);
1768
1769 switch (n->state) { 1783 switch (n->state) {
1770 case GNUNET_TRANSPORT_PS_SYN_SENT: 1784 case GNUNET_TRANSPORT_PS_SYN_SENT:
1771 /* Remove address and request an additional one */ 1785 /* Remove address and request an additional one */
1772 unset_primary_address (n); 1786 unset_primary_address (n);
1773 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_INIT_ATS, 1787 set_state_and_timeout (n,
1788 GNUNET_TRANSPORT_PS_INIT_ATS,
1774 GNUNET_TIME_relative_to_absolute (FAST_RECONNECT_TIMEOUT)); 1789 GNUNET_TIME_relative_to_absolute (FAST_RECONNECT_TIMEOUT));
1775 break; 1790 break;
1776 case GNUNET_TRANSPORT_PS_RECONNECT_SENT: 1791 case GNUNET_TRANSPORT_PS_RECONNECT_SENT:
1777 /* Remove address and request an additional one */ 1792 /* Remove address and request an additional one */
1778 unset_primary_address (n); 1793 unset_primary_address (n);
1779 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_RECONNECT_ATS, 1794 set_state_and_timeout (n,
1780 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT)); 1795 GNUNET_TRANSPORT_PS_RECONNECT_ATS,
1796 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
1781 break; 1797 break;
1782 case GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT: 1798 case GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT:
1783 /* Remove address and request and go back to primary address */ 1799 /* Remove address and request and go back to primary address */
1784 GNUNET_STATISTICS_update (GST_stats, gettext_noop 1800 GNUNET_STATISTICS_update (GST_stats,
1785 ("# Failed attempts to switch addresses (failed to send SYN CONT)"), 1, GNUNET_NO); 1801 gettext_noop ("# Failed attempts to switch addresses (failed to send SYN CONT)"),
1786 unset_alternative_address (n); 1802 1,
1787 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECTED, 1803 GNUNET_NO);
1788 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT)); 1804 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1805 "Switch failed, cleaning up alternative address\n");
1806 free_address (&n->alternative_address);
1807 set_state_and_timeout (n,
1808 GNUNET_TRANSPORT_PS_CONNECTED,
1809 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
1789 break; 1810 break;
1790 default: 1811 default:
1791 disconnect_neighbour (n); 1812 disconnect_neighbour (n);
@@ -1793,6 +1814,7 @@ send_session_connect_cont (void *cls,
1793 } 1814 }
1794} 1815}
1795 1816
1817
1796/** 1818/**
1797 * Send a SYN message via the given address. 1819 * Send a SYN message via the given address.
1798 * 1820 *
@@ -1805,24 +1827,14 @@ send_syn (struct NeighbourAddress *na)
1805 struct TransportSynMessage connect_msg; 1827 struct TransportSynMessage connect_msg;
1806 struct NeighbourMapEntry *n; 1828 struct NeighbourMapEntry *n;
1807 1829
1830 GNUNET_assert (NULL != na->session);
1808 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1831 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1809 "Sending SYN message to peer `%s'\n", 1832 "Sending SYN message to peer `%s' at %s\n",
1810 GNUNET_i2s (&na->address->peer)); 1833 GNUNET_i2s (&na->address->peer),
1834 GST_plugins_a2s (na->address));
1811 1835
1812 if (NULL == (papi = GST_plugins_find (na->address->transport_name))) 1836 papi = GST_plugins_find (na->address->transport_name);
1813 { 1837 GNUNET_assert (NULL != papi);
1814 GNUNET_break (0);
1815 return;
1816 }
1817 if (NULL == na->session)
1818 na->session = papi->get_session (papi->cls, na->address);
1819 if (NULL == na->session)
1820 {
1821 GNUNET_break (0);
1822 return;
1823 }
1824 GST_ats_new_session (na->address,
1825 na->session);
1826 GNUNET_STATISTICS_update (GST_stats, 1838 GNUNET_STATISTICS_update (GST_stats,
1827 gettext_noop 1839 gettext_noop
1828 ("# SYN messages sent"), 1840 ("# SYN messages sent"),
@@ -1835,46 +1847,56 @@ send_syn (struct NeighbourAddress *na)
1835 if (-1 == 1847 if (-1 ==
1836 papi->send (papi->cls, 1848 papi->send (papi->cls,
1837 na->session, 1849 na->session,
1838 (const char *) &connect_msg, sizeof (struct TransportSynMessage), 1850 (const char *) &connect_msg,
1851 sizeof (struct TransportSynMessage),
1839 UINT_MAX, 1852 UINT_MAX,
1840 SETUP_CONNECTION_TIMEOUT, 1853 SETUP_CONNECTION_TIMEOUT,
1841 send_session_connect_cont, NULL)) 1854 &send_session_syn_cont, NULL))
1842 { 1855 {
1843 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1856 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1844 _("Failed to transmit SYN message via plugin to %s\n"), 1857 _("Failed to transmit SYN message to %s\n"),
1845 GST_plugins_a2s (na->address)); 1858 GST_plugins_a2s (na->address));
1846
1847 n = lookup_neighbour (&na->address->peer); 1859 n = lookup_neighbour (&na->address->peer);
1848 if (NULL == n) 1860 if (NULL == n)
1849 { 1861 {
1850 GNUNET_break (0); 1862 GNUNET_break (0);
1851 return; 1863 return;
1852 } 1864 }
1853
1854 switch (n->state) { 1865 switch (n->state) {
1855 case GNUNET_TRANSPORT_PS_SYN_SENT: 1866 case GNUNET_TRANSPORT_PS_SYN_SENT:
1856 /* Remove address and request and additional one */ 1867 /* Remove address and request and additional one */
1868 GNUNET_assert (na == &n->primary_address);
1857 unset_primary_address (n); 1869 unset_primary_address (n);
1858 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_INIT_ATS, 1870 set_state_and_timeout (n,
1859 GNUNET_TIME_relative_to_absolute (FAST_RECONNECT_TIMEOUT)); 1871 GNUNET_TRANSPORT_PS_INIT_ATS,
1872 GNUNET_TIME_relative_to_absolute (FAST_RECONNECT_TIMEOUT));
1860 /* Hard failure to send the SYN message with this address: 1873 /* Hard failure to send the SYN message with this address:
1861 Destroy address and session */ 1874 Destroy address and session */
1862 break; 1875 break;
1863 case GNUNET_TRANSPORT_PS_RECONNECT_SENT: 1876 case GNUNET_TRANSPORT_PS_RECONNECT_SENT:
1864 /* Remove address and request an additional one */ 1877 /* Remove address and request an additional one */
1878 GNUNET_assert (na == &n->primary_address);
1865 unset_primary_address (n); 1879 unset_primary_address (n);
1866 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_RECONNECT_ATS, 1880 set_state_and_timeout (n,
1867 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT)); 1881 GNUNET_TRANSPORT_PS_RECONNECT_ATS,
1882 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
1868 break; 1883 break;
1869 case GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT: 1884 case GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT:
1870 GNUNET_STATISTICS_update (GST_stats, gettext_noop 1885 GNUNET_assert (na == &n->alternative_address);
1871 ("# Failed attempts to switch addresses (failed to send SYN)"), 1, GNUNET_NO); 1886 GNUNET_STATISTICS_update (GST_stats,
1887 gettext_noop ("# Failed attempts to switch addresses (failed to send SYN)"),
1888 1,
1889 GNUNET_NO);
1872 /* Remove address and request an additional one */ 1890 /* Remove address and request an additional one */
1873 unset_alternative_address (n); 1891 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1874 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECTED, 1892 "Switch failed, cleaning up alternative address\n");
1875 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT)); 1893 free_address (&n->alternative_address);
1894 set_state_and_timeout (n,
1895 GNUNET_TRANSPORT_PS_CONNECTED,
1896 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
1876 break; 1897 break;
1877 default: 1898 default:
1899 GNUNET_break (0);
1878 disconnect_neighbour (n); 1900 disconnect_neighbour (n);
1879 break; 1901 break;
1880 } 1902 }
@@ -1886,14 +1908,23 @@ send_syn (struct NeighbourAddress *na)
1886 1908
1887 1909
1888/** 1910/**
1889 * FIXME. 1911 * Continuation called from our attempt to transmitted our
1912 * #GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_SYN_ACK to the specified @a
1913 * target. Continue processing based on the @a result. Specifically,
1914 * if we failed to transmit, discard the address we used.
1915 *
1916 * @param cls NULL
1917 * @param target which peer received the transmission
1918 * @param result #GNUNET_OK if sending worked
1919 * @param size_payload how many bytes of payload were sent (ignored)
1920 * @param size_on_wire how much bandwidth was consumed on the wire (ignored)
1890 */ 1921 */
1891static void 1922static void
1892send_session_connect_ack_cont (void *cls, 1923send_session_syn_ack_cont (void *cls,
1893 const struct GNUNET_PeerIdentity *target, 1924 const struct GNUNET_PeerIdentity *target,
1894 int result, 1925 int result,
1895 size_t size_payload, 1926 size_t size_payload,
1896 size_t size_on_wire) 1927 size_t size_on_wire)
1897{ 1928{
1898 struct NeighbourMapEntry *n; 1929 struct NeighbourMapEntry *n;
1899 1930
@@ -1917,33 +1948,35 @@ send_session_connect_ack_cont (void *cls,
1917 return; 1948 return;
1918 1949
1919 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1950 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1920 _("Failed to send SYN_ACK message to peer `%s' using address `%s' session %p\n"), 1951 _("Failed to send SYN_ACK message to peer `%s' using address `%s'\n"),
1921 GNUNET_i2s (target), 1952 GNUNET_i2s (target),
1922 GST_plugins_a2s (n->primary_address.address), 1953 GST_plugins_a2s (n->primary_address.address));
1923 n->primary_address.session);
1924 1954
1925 /* Remove address and request and additional one */ 1955 /* Remove address and request and additional one */
1956 /* FIXME: what if the neighbour's primary address
1957 changed in the meantime? Might want to instead
1958 pass "something" around in closure to be sure. */
1926 unset_primary_address (n); 1959 unset_primary_address (n);
1927 n->ack_state = ACK_SEND_SYN_ACK; 1960 n->ack_state = ACK_SEND_SYN_ACK;
1928 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_SYN_RECV_ATS, 1961 set_state_and_timeout (n,
1962 GNUNET_TRANSPORT_PS_SYN_RECV_ATS,
1929 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT)); 1963 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
1930 return;
1931} 1964}
1932 1965
1933 1966
1934/** 1967/**
1935 * Send a SYN_ACK message via the given address. 1968 * Send a SYN_ACK message via the given address.
1936 * 1969 *
1937 * @param address address to use 1970 * @param na address and session to use
1938 * @param session session to use
1939 * @param timestamp timestamp to use for the ACK message 1971 * @param timestamp timestamp to use for the ACK message
1940 * @return GNUNET_SYSERR if sending immediately failed, GNUNET_OK otherwise 1972 * @return #GNUNET_SYSERR if sending immediately failed, #GNUNET_OK otherwise
1941 */ 1973 */
1942static void 1974static void
1943send_connect_ack_message (const struct GNUNET_HELLO_Address *address, 1975send_syn_ack_message (struct NeighbourAddress *na,
1944 struct Session *session, 1976 struct GNUNET_TIME_Absolute timestamp)
1945 struct GNUNET_TIME_Absolute timestamp)
1946{ 1977{
1978 const struct GNUNET_HELLO_Address *address = na->address;
1979 struct Session *session = na->session;
1947 struct GNUNET_TRANSPORT_PluginFunctions *papi; 1980 struct GNUNET_TRANSPORT_PluginFunctions *papi;
1948 struct TransportSynMessage connect_msg; 1981 struct TransportSynMessage connect_msg;
1949 struct NeighbourMapEntry *n; 1982 struct NeighbourMapEntry *n;
@@ -1958,13 +1991,15 @@ send_connect_ack_message (const struct GNUNET_HELLO_Address *address,
1958 return; 1991 return;
1959 } 1992 }
1960 if (NULL == session) 1993 if (NULL == session)
1961 session = papi->get_session (papi->cls, address); 1994 session = papi->get_session (papi->cls,
1995 address);
1962 if (NULL == session) 1996 if (NULL == session)
1963 { 1997 {
1964 GNUNET_break (0); 1998 GNUNET_break (0);
1965 return; 1999 return;
1966 } 2000 }
1967 GST_ats_new_session (address, session); 2001 GST_ats_new_session (address,
2002 session);
1968 GNUNET_STATISTICS_update (GST_stats, 2003 GNUNET_STATISTICS_update (GST_stats,
1969 gettext_noop 2004 gettext_noop
1970 ("# SYN_ACK messages sent"), 2005 ("# SYN_ACK messages sent"),
@@ -1974,15 +2009,17 @@ send_connect_ack_message (const struct GNUNET_HELLO_Address *address,
1974 connect_msg.reserved = htonl (0); 2009 connect_msg.reserved = htonl (0);
1975 connect_msg.timestamp = GNUNET_TIME_absolute_hton (timestamp); 2010 connect_msg.timestamp = GNUNET_TIME_absolute_hton (timestamp);
1976 2011
1977 if (GNUNET_SYSERR == papi->send (papi->cls, 2012 if (GNUNET_SYSERR ==
1978 session, 2013 papi->send (papi->cls,
1979 (const char *) &connect_msg, sizeof (struct TransportSynMessage), 2014 session,
1980 UINT_MAX, 2015 (const char *) &connect_msg,
1981 GNUNET_TIME_UNIT_FOREVER_REL, 2016 sizeof (struct TransportSynMessage),
1982 send_session_connect_ack_cont, NULL)) 2017 UINT_MAX,
2018 GNUNET_TIME_UNIT_FOREVER_REL,
2019 &send_session_syn_ack_cont, NULL))
1983 { 2020 {
1984 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 2021 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1985 _("Failed to transmit SYN_ACK message via plugin to %s\n"), 2022 _("Failed to transmit SYN_ACK message to %s\n"),
1986 GST_plugins_a2s (address)); 2023 GST_plugins_a2s (address));
1987 2024
1988 n = lookup_neighbour (&address->peer); 2025 n = lookup_neighbour (&address->peer);
@@ -1994,11 +2031,11 @@ send_connect_ack_message (const struct GNUNET_HELLO_Address *address,
1994 /* Remove address and request and additional one */ 2031 /* Remove address and request and additional one */
1995 unset_primary_address (n); 2032 unset_primary_address (n);
1996 n->ack_state = ACK_SEND_SYN_ACK; 2033 n->ack_state = ACK_SEND_SYN_ACK;
1997 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_SYN_RECV_ATS, 2034 set_state_and_timeout (n,
1998 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT)); 2035 GNUNET_TRANSPORT_PS_SYN_RECV_ATS,
2036 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
1999 return; 2037 return;
2000 } 2038 }
2001
2002} 2039}
2003 2040
2004 2041
@@ -2056,10 +2093,6 @@ setup_neighbour (const struct GNUNET_PeerIdentity *peer)
2056 n->id = *peer; 2093 n->id = *peer;
2057 n->ack_state = ACK_UNDEFINED; 2094 n->ack_state = ACK_UNDEFINED;
2058 n->last_util_transmission = GNUNET_TIME_absolute_get(); 2095 n->last_util_transmission = GNUNET_TIME_absolute_get();
2059 n->util_payload_bytes_recv = 0;
2060 n->util_payload_bytes_sent = 0;
2061 n->util_total_bytes_recv = 0;
2062 n->util_total_bytes_sent = 0;
2063 GNUNET_BANDWIDTH_tracker_init (&n->in_tracker, 2096 GNUNET_BANDWIDTH_tracker_init (&n->in_tracker,
2064 &inbound_bw_tracker_update, 2097 &inbound_bw_tracker_update,
2065 n, 2098 n,
@@ -2073,6 +2106,9 @@ setup_neighbour (const struct GNUNET_PeerIdentity *peer)
2073 GNUNET_CONTAINER_multipeermap_put (neighbours, 2106 GNUNET_CONTAINER_multipeermap_put (neighbours,
2074 &n->id, n, 2107 &n->id, n,
2075 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 2108 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
2109 n->suggest_handle = GNUNET_ATS_connectivity_suggest (GST_ats_connect,
2110 peer);
2111
2076 return n; 2112 return n;
2077} 2113}
2078 2114
@@ -2157,10 +2193,6 @@ try_connect_bl_check_cont (void *cls,
2157 set_state_and_timeout (n, 2193 set_state_and_timeout (n,
2158 GNUNET_TRANSPORT_PS_INIT_ATS, 2194 GNUNET_TRANSPORT_PS_INIT_ATS,
2159 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT)); 2195 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
2160 GNUNET_ATS_reset_backoff (GST_ats, peer);
2161 GNUNET_assert (NULL == n->suggest_handle);
2162 n->suggest_handle = GNUNET_ATS_connectivity_suggest (GST_ats_connect,
2163 peer);
2164} 2196}
2165 2197
2166 2198
@@ -2304,17 +2336,16 @@ GST_neighbours_handle_session_syn (const struct GNUNET_MessageHeader *message,
2304 { 2336 {
2305 case GNUNET_TRANSPORT_PS_NOT_CONNECTED: 2337 case GNUNET_TRANSPORT_PS_NOT_CONNECTED:
2306 /* Request an address from ATS to send SYN_ACK to this peer */ 2338 /* Request an address from ATS to send SYN_ACK to this peer */
2307 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_SYN_RECV_ATS, 2339 set_state_and_timeout (n,
2308 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT)); 2340 GNUNET_TRANSPORT_PS_SYN_RECV_ATS,
2309 if (NULL == n->suggest_handle) 2341 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
2310 n->suggest_handle = GNUNET_ATS_connectivity_suggest (GST_ats_connect,
2311 peer);
2312 break; 2342 break;
2313 case GNUNET_TRANSPORT_PS_INIT_ATS: 2343 case GNUNET_TRANSPORT_PS_INIT_ATS:
2314 /* SYN message takes priority over us asking ATS for address: 2344 /* SYN message takes priority over us asking ATS for address:
2315 * Wait for ATS to suggest an address and send SYN_ACK */ 2345 * Wait for ATS to suggest an address and send SYN_ACK */
2316 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_SYN_RECV_ATS, 2346 set_state_and_timeout (n,
2317 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT)); 2347 GNUNET_TRANSPORT_PS_SYN_RECV_ATS,
2348 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
2318 break; 2349 break;
2319 case GNUNET_TRANSPORT_PS_SYN_RECV_ATS: 2350 case GNUNET_TRANSPORT_PS_SYN_RECV_ATS:
2320 /* We already wait for an address to send an SYN_ACK */ 2351 /* We already wait for an address to send an SYN_ACK */
@@ -2323,16 +2354,16 @@ GST_neighbours_handle_session_syn (const struct GNUNET_MessageHeader *message,
2323 case GNUNET_TRANSPORT_PS_SYN_RECV_ACK: 2354 case GNUNET_TRANSPORT_PS_SYN_RECV_ACK:
2324 /* Send ACK immediately */ 2355 /* Send ACK immediately */
2325 n->ack_state = ACK_SEND_ACK; 2356 n->ack_state = ACK_SEND_ACK;
2326 send_connect_ack_message (n->primary_address.address, 2357 send_syn_ack_message (&n->primary_address,
2327 n->primary_address.session, ts); 2358 ts);
2328 break; 2359 break;
2329 case GNUNET_TRANSPORT_PS_CONNECTED: 2360 case GNUNET_TRANSPORT_PS_CONNECTED:
2330 /* we are already connected and can thus send the ACK immediately */ 2361 /* we are already connected and can thus send the ACK immediately */
2331 GNUNET_assert (NULL != n->primary_address.address); 2362 GNUNET_assert (NULL != n->primary_address.address);
2332 GNUNET_assert (NULL != n->primary_address.session); 2363 GNUNET_assert (NULL != n->primary_address.session);
2333 n->ack_state = ACK_SEND_ACK; 2364 n->ack_state = ACK_SEND_ACK;
2334 send_connect_ack_message (n->primary_address.address, 2365 send_syn_ack_message (&n->primary_address,
2335 n->primary_address.session, ts); 2366 ts);
2336 break; 2367 break;
2337 case GNUNET_TRANSPORT_PS_RECONNECT_ATS: 2368 case GNUNET_TRANSPORT_PS_RECONNECT_ATS:
2338 /* We wait for ATS address suggestion */ 2369 /* We wait for ATS address suggestion */
@@ -2341,8 +2372,8 @@ GST_neighbours_handle_session_syn (const struct GNUNET_MessageHeader *message,
2341 /* We received a SYN message while waiting for a SYN_ACK in fast 2372 /* We received a SYN message while waiting for a SYN_ACK in fast
2342 * reconnect. Send SYN_ACK immediately */ 2373 * reconnect. Send SYN_ACK immediately */
2343 n->ack_state = ACK_SEND_ACK; 2374 n->ack_state = ACK_SEND_ACK;
2344 send_connect_ack_message (n->primary_address.address, 2375 send_syn_ack_message (&n->primary_address,
2345 n->primary_address.session, n->connect_ack_timestamp); 2376 n->connect_ack_timestamp);
2346 break; 2377 break;
2347 case GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT: 2378 case GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT:
2348 /* We are already connected and can thus send the ACK immediately; 2379 /* We are already connected and can thus send the ACK immediately;
@@ -2351,8 +2382,8 @@ GST_neighbours_handle_session_syn (const struct GNUNET_MessageHeader *message,
2351 GNUNET_assert (NULL != n->primary_address.address); 2382 GNUNET_assert (NULL != n->primary_address.address);
2352 GNUNET_assert (NULL != n->primary_address.session); 2383 GNUNET_assert (NULL != n->primary_address.session);
2353 n->ack_state = ACK_SEND_ACK; 2384 n->ack_state = ACK_SEND_ACK;
2354 send_connect_ack_message (n->primary_address.address, 2385 send_syn_ack_message (&n->primary_address,
2355 n->primary_address.session, ts); 2386 ts);
2356 break; 2387 break;
2357 case GNUNET_TRANSPORT_PS_DISCONNECT: 2388 case GNUNET_TRANSPORT_PS_DISCONNECT:
2358 /* Get rid of remains and re-try */ 2389 /* Get rid of remains and re-try */
@@ -2362,10 +2393,9 @@ GST_neighbours_handle_session_syn (const struct GNUNET_MessageHeader *message,
2362 n->ack_state = ACK_SEND_SYN_ACK; 2393 n->ack_state = ACK_SEND_SYN_ACK;
2363 n->connect_ack_timestamp = ts; 2394 n->connect_ack_timestamp = ts;
2364 /* Request an address for the peer */ 2395 /* Request an address for the peer */
2365 n->suggest_handle = GNUNET_ATS_connectivity_suggest (GST_ats_connect, 2396 set_state_and_timeout (n,
2366 peer); 2397 GNUNET_TRANSPORT_PS_SYN_RECV_ATS,
2367 GNUNET_ATS_reset_backoff (GST_ats, peer); 2398 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
2368 set_state (n, GNUNET_TRANSPORT_PS_SYN_RECV_ATS);
2369 break; 2399 break;
2370 case GNUNET_TRANSPORT_PS_DISCONNECT_FINISHED: 2400 case GNUNET_TRANSPORT_PS_DISCONNECT_FINISHED:
2371 /* should not be possible */ 2401 /* should not be possible */
@@ -2405,7 +2435,6 @@ try_run_fast_ats_update (const struct GNUNET_HELLO_Address *address,
2405 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out) 2435 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out)
2406{ 2436{
2407 struct NeighbourMapEntry *n; 2437 struct NeighbourMapEntry *n;
2408 int connected;
2409 2438
2410 n = lookup_neighbour (&address->peer); 2439 n = lookup_neighbour (&address->peer);
2411 if ( (NULL == n) || 2440 if ( (NULL == n) ||
@@ -2419,16 +2448,7 @@ try_run_fast_ats_update (const struct GNUNET_HELLO_Address *address,
2419 { 2448 {
2420 /* switch to a different session, but keeping same address; could 2449 /* switch to a different session, but keeping same address; could
2421 happen if there is a 2nd inbound connection */ 2450 happen if there is a 2nd inbound connection */
2422 connected = GNUNET_TRANSPORT_is_connected (n->state);
2423 if (GNUNET_YES == connected)
2424 GST_ats_set_in_use (n->primary_address.address,
2425 n->primary_address.session,
2426 GNUNET_NO);
2427 n->primary_address.session = session; 2451 n->primary_address.session = session;
2428 if (GNUNET_YES == connected)
2429 GST_ats_set_in_use (n->primary_address.address,
2430 n->primary_address.session,
2431 GNUNET_YES);
2432 } 2452 }
2433 n->primary_address.bandwidth_in = bandwidth_in; 2453 n->primary_address.bandwidth_in = bandwidth_in;
2434 n->primary_address.bandwidth_out = bandwidth_out; 2454 n->primary_address.bandwidth_out = bandwidth_out;
@@ -2470,8 +2490,10 @@ switch_address_bl_check_cont (void *cls,
2470 "# ATS suggestions ignored (blacklist denied)", 2490 "# ATS suggestions ignored (blacklist denied)",
2471 1, 2491 1,
2472 GNUNET_NO); 2492 GNUNET_NO);
2473 /* FIXME: tell plugin to force killing session here and now! */ 2493 /* FIXME: tell plugin to force killing session here and now
2474 /* FIXME: Let ATS know that the suggested address did not work! */ 2494 (note: _proper_ plugin API for this does not yet exist) */
2495 GST_ats_block_address (blc_ctx->address,
2496 blc_ctx->session);
2475 goto cleanup; 2497 goto cleanup;
2476 } 2498 }
2477 2499
@@ -2501,10 +2523,11 @@ switch_address_bl_check_cont (void *cls,
2501 GNUNET_NO); 2523 GNUNET_NO);
2502 /* No session could be obtained, remove blacklist check and clean up */ 2524 /* No session could be obtained, remove blacklist check and clean up */
2503 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2525 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2504 "Failed to obtain new session for peer `%s' and address '%s'\n", 2526 "Failed to obtain new session for peer `%s' and address '%s'\n",
2505 GNUNET_i2s (&blc_ctx->address->peer), 2527 GNUNET_i2s (&blc_ctx->address->peer),
2506 GST_plugins_a2s (blc_ctx->address)); 2528 GST_plugins_a2s (blc_ctx->address));
2507 /* FIXME: Let ATS know that the suggested address did not work! */ 2529 GST_ats_block_address (blc_ctx->address,
2530 blc_ctx->session);
2508 goto cleanup; 2531 goto cleanup;
2509 } 2532 }
2510 2533
@@ -2526,15 +2549,16 @@ switch_address_bl_check_cont (void *cls,
2526 } 2549 }
2527 2550
2528 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 2551 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2529 "Peer `%s' switches to address `%s' session %p\n", 2552 "Peer `%s' switches to address `%s'\n",
2530 GNUNET_i2s (&blc_ctx->address->peer), 2553 GNUNET_i2s (&blc_ctx->address->peer),
2531 GST_plugins_a2s (blc_ctx->address), 2554 GST_plugins_a2s (blc_ctx->address));
2532 blc_ctx->session);
2533 2555
2534 switch (n->state) 2556 switch (n->state)
2535 { 2557 {
2536 case GNUNET_TRANSPORT_PS_NOT_CONNECTED: 2558 case GNUNET_TRANSPORT_PS_NOT_CONNECTED:
2537 GNUNET_break (0); 2559 GNUNET_break (0);
2560 GST_ats_block_address (blc_ctx->address,
2561 blc_ctx->session);
2538 free_neighbour (n); 2562 free_neighbour (n);
2539 return; 2563 return;
2540 case GNUNET_TRANSPORT_PS_INIT_ATS: 2564 case GNUNET_TRANSPORT_PS_INIT_ATS:
@@ -2550,9 +2574,8 @@ switch_address_bl_check_cont (void *cls,
2550 { 2574 {
2551 /* Send pending SYN_ACK message */ 2575 /* Send pending SYN_ACK message */
2552 n->ack_state = ACK_SEND_ACK; 2576 n->ack_state = ACK_SEND_ACK;
2553 send_connect_ack_message (n->primary_address.address, 2577 send_syn_ack_message (&n->primary_address,
2554 n->primary_address.session, 2578 n->connect_ack_timestamp);
2555 n->connect_ack_timestamp);
2556 } 2579 }
2557 set_state_and_timeout (n, 2580 set_state_and_timeout (n,
2558 GNUNET_TRANSPORT_PS_SYN_SENT, 2581 GNUNET_TRANSPORT_PS_SYN_SENT,
@@ -2573,9 +2596,8 @@ switch_address_bl_check_cont (void *cls,
2573 { 2596 {
2574 /* Send pending SYN_ACK message */ 2597 /* Send pending SYN_ACK message */
2575 n->ack_state = ACK_SEND_ACK; 2598 n->ack_state = ACK_SEND_ACK;
2576 send_connect_ack_message (n->primary_address.address, 2599 send_syn_ack_message (&n->primary_address,
2577 n->primary_address.session, 2600 n->connect_ack_timestamp);
2578 n->connect_ack_timestamp);
2579 } 2601 }
2580 set_state_and_timeout (n, 2602 set_state_and_timeout (n,
2581 GNUNET_TRANSPORT_PS_SYN_SENT, 2603 GNUNET_TRANSPORT_PS_SYN_SENT,
@@ -2595,9 +2617,8 @@ switch_address_bl_check_cont (void *cls,
2595 set_state_and_timeout (n, 2617 set_state_and_timeout (n,
2596 GNUNET_TRANSPORT_PS_SYN_RECV_ACK, 2618 GNUNET_TRANSPORT_PS_SYN_RECV_ACK,
2597 GNUNET_TIME_relative_to_absolute (SETUP_CONNECTION_TIMEOUT)); 2619 GNUNET_TIME_relative_to_absolute (SETUP_CONNECTION_TIMEOUT));
2598 send_connect_ack_message (n->primary_address.address, 2620 send_syn_ack_message (&n->primary_address,
2599 n->primary_address.session, 2621 n->connect_ack_timestamp);
2600 n->connect_ack_timestamp);
2601 if ( (ACK_SEND_SYN_ACK == n->ack_state) || 2622 if ( (ACK_SEND_SYN_ACK == n->ack_state) ||
2602 (ACK_UNDEFINED == n->ack_state) ) 2623 (ACK_UNDEFINED == n->ack_state) )
2603 n->ack_state = ACK_SEND_ACK; 2624 n->ack_state = ACK_SEND_ACK;
@@ -2608,9 +2629,8 @@ switch_address_bl_check_cont (void *cls,
2608 if ( (ACK_SEND_SYN_ACK == n->ack_state) ) 2629 if ( (ACK_SEND_SYN_ACK == n->ack_state) )
2609 { 2630 {
2610 n->ack_state = ACK_SEND_ACK; 2631 n->ack_state = ACK_SEND_ACK;
2611 send_connect_ack_message (n->primary_address.address, 2632 send_syn_ack_message (&n->primary_address,
2612 n->primary_address.session, 2633 n->connect_ack_timestamp);
2613 n->connect_ack_timestamp);
2614 } 2634 }
2615 set_primary_address (n, 2635 set_primary_address (n,
2616 blc_ctx->address, 2636 blc_ctx->address,
@@ -2625,18 +2645,7 @@ switch_address_bl_check_cont (void *cls,
2625 case GNUNET_TRANSPORT_PS_CONNECTED: 2645 case GNUNET_TRANSPORT_PS_CONNECTED:
2626 GNUNET_assert (NULL != n->primary_address.address); 2646 GNUNET_assert (NULL != n->primary_address.address);
2627 GNUNET_assert (NULL != n->primary_address.session); 2647 GNUNET_assert (NULL != n->primary_address.session);
2628 if (n->primary_address.session == blc_ctx->session) 2648 GNUNET_break (n->primary_address.session != blc_ctx->session);
2629 {
2630 /* not an address change, just a quota change */
2631 // FIXME: this case should have been caught above!
2632 set_primary_address (n,
2633 blc_ctx->address,
2634 blc_ctx->session,
2635 blc_ctx->bandwidth_in,
2636 blc_ctx->bandwidth_out,
2637 GNUNET_YES);
2638 break;
2639 }
2640 /* ATS asks us to switch a life connection; see if we can get 2649 /* ATS asks us to switch a life connection; see if we can get
2641 a SYN_ACK on it before we actually do this! */ 2650 a SYN_ACK on it before we actually do this! */
2642 set_alternative_address (n, 2651 set_alternative_address (n,
@@ -2644,7 +2653,8 @@ switch_address_bl_check_cont (void *cls,
2644 blc_ctx->session, 2653 blc_ctx->session,
2645 blc_ctx->bandwidth_in, 2654 blc_ctx->bandwidth_in,
2646 blc_ctx->bandwidth_out); 2655 blc_ctx->bandwidth_out);
2647 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT, 2656 set_state_and_timeout (n,
2657 GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT,
2648 GNUNET_TIME_relative_to_absolute (SETUP_CONNECTION_TIMEOUT)); 2658 GNUNET_TIME_relative_to_absolute (SETUP_CONNECTION_TIMEOUT));
2649 GNUNET_STATISTICS_update (GST_stats, 2659 GNUNET_STATISTICS_update (GST_stats,
2650 gettext_noop ("# Attempts to switch addresses"), 2660 gettext_noop ("# Attempts to switch addresses"),
@@ -2663,9 +2673,8 @@ switch_address_bl_check_cont (void *cls,
2663 { 2673 {
2664 /* Send pending SYN_ACK message */ 2674 /* Send pending SYN_ACK message */
2665 n->ack_state = ACK_SEND_ACK; 2675 n->ack_state = ACK_SEND_ACK;
2666 send_connect_ack_message (n->primary_address.address, 2676 send_syn_ack_message (&n->primary_address,
2667 n->primary_address.session, 2677 n->connect_ack_timestamp);
2668 n->connect_ack_timestamp);
2669 } 2678 }
2670 set_state_and_timeout (n, 2679 set_state_and_timeout (n,
2671 GNUNET_TRANSPORT_PS_RECONNECT_SENT, 2680 GNUNET_TRANSPORT_PS_RECONNECT_SENT,
@@ -2687,13 +2696,17 @@ switch_address_bl_check_cont (void *cls,
2687 send_syn (&n->primary_address); 2696 send_syn (&n->primary_address);
2688 break; 2697 break;
2689 case GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT: 2698 case GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT:
2690 if ( (0 == GNUNET_HELLO_address_cmp(n->primary_address.address, 2699 if ( (0 == GNUNET_HELLO_address_cmp (n->primary_address.address,
2691 blc_ctx->address)) && 2700 blc_ctx->address)) &&
2692 (n->primary_address.session == blc_ctx->session) ) 2701 (n->primary_address.session == blc_ctx->session) )
2693 { 2702 {
2694 /* ATS switches back to still-active session */ 2703 /* ATS switches back to still-active session */
2704 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2705 "ATS double-switched, cleaning up alternative address\n");
2695 free_address (&n->alternative_address); 2706 free_address (&n->alternative_address);
2696 set_state (n, GNUNET_TRANSPORT_PS_CONNECTED); 2707 set_state_and_timeout (n,
2708 GNUNET_TRANSPORT_PS_CONNECTED,
2709 n->timeout);
2697 break; 2710 break;
2698 } 2711 }
2699 /* ATS asks us to switch a life connection, send */ 2712 /* ATS asks us to switch a life connection, send */
@@ -2737,7 +2750,11 @@ switch_address_bl_check_cont (void *cls,
2737 * For the given peer, switch to this address. 2750 * For the given peer, switch to this address.
2738 * 2751 *
2739 * Before accepting this addresses and actively using it, a blacklist check 2752 * Before accepting this addresses and actively using it, a blacklist check
2740 * is performed. If this blacklist check fails the address will be destroyed. 2753 * is performed.
2754 *
2755 * If any check fails or the suggestion can somehow not be followed, we
2756 * MUST call #GST_ats_block_address() to tell ATS that the suggestion
2757 * could not be satisfied and force ATS to do something else.
2741 * 2758 *
2742 * @param address address of the other peer, 2759 * @param address address of the other peer,
2743 * @param session session to use or NULL if transport should initiate a session 2760 * @param session session to use or NULL if transport should initiate a session
@@ -2755,9 +2772,6 @@ GST_neighbours_switch_to_address (const struct GNUNET_HELLO_Address *address,
2755 struct GST_BlacklistCheck *blc; 2772 struct GST_BlacklistCheck *blc;
2756 struct BlacklistCheckSwitchContext *blc_ctx; 2773 struct BlacklistCheckSwitchContext *blc_ctx;
2757 2774
2758 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2759 "ATS has decided on an address for peer %s\n",
2760 GNUNET_i2s (&address->peer));
2761 GNUNET_assert (NULL != address->transport_name); 2775 GNUNET_assert (NULL != address->transport_name);
2762 if (GNUNET_OK == 2776 if (GNUNET_OK ==
2763 try_run_fast_ats_update (address, 2777 try_run_fast_ats_update (address,
@@ -2771,6 +2785,8 @@ GST_neighbours_switch_to_address (const struct GNUNET_HELLO_Address *address,
2771 { 2785 {
2772 /* we don't have the plugin for this address */ 2786 /* we don't have the plugin for this address */
2773 GNUNET_break (0); 2787 GNUNET_break (0);
2788 GST_ats_block_address (address,
2789 session);
2774 return; 2790 return;
2775 } 2791 }
2776 if ((NULL == session) && 2792 if ((NULL == session) &&
@@ -2779,14 +2795,13 @@ GST_neighbours_switch_to_address (const struct GNUNET_HELLO_Address *address,
2779 { 2795 {
2780 /* This is a inbound address and we do not have a session to use! */ 2796 /* This is a inbound address and we do not have a session to use! */
2781 GNUNET_break (0); 2797 GNUNET_break (0);
2798 GST_ats_block_address (address,
2799 session);
2782 return; 2800 return;
2783 } 2801 }
2784 2802
2785 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2803 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2786 "ATS suggests %s address '%s' for peer `%s'\n", 2804 "ATS suggests address '%s' for peer `%s'\n",
2787 GNUNET_HELLO_address_check_option (address,
2788 GNUNET_HELLO_ADDRESS_INFO_INBOUND)
2789 ? "inbound" : "outbound",
2790 GST_plugins_a2s (address), 2805 GST_plugins_a2s (address),
2791 GNUNET_i2s (&address->peer)); 2806 GNUNET_i2s (&address->peer));
2792 2807
@@ -2831,7 +2846,7 @@ send_utilization_data (void *cls,
2831 uint32_t bps_out; 2846 uint32_t bps_out;
2832 struct GNUNET_TIME_Relative delta; 2847 struct GNUNET_TIME_Relative delta;
2833 2848
2834 if (GNUNET_TRANSPORT_PS_CONNECTED != n->state) 2849 if (GNUNET_YES != test_connected (n))
2835 return GNUNET_OK; 2850 return GNUNET_OK;
2836 delta = GNUNET_TIME_absolute_get_difference (n->last_util_transmission, 2851 delta = GNUNET_TIME_absolute_get_difference (n->last_util_transmission,
2837 GNUNET_TIME_absolute_get ()); 2852 GNUNET_TIME_absolute_get ());
@@ -2894,13 +2909,13 @@ utilization_transmission (void *cls,
2894 const struct GNUNET_SCHEDULER_TaskContext *tc) 2909 const struct GNUNET_SCHEDULER_TaskContext *tc)
2895{ 2910{
2896 util_transmission_tk = NULL; 2911 util_transmission_tk = NULL;
2897 2912 GNUNET_CONTAINER_multipeermap_iterate (neighbours,
2898 if (0 < GNUNET_CONTAINER_multipeermap_size (neighbours)) 2913 &send_utilization_data,
2899 GNUNET_CONTAINER_multipeermap_iterate (neighbours, send_utilization_data, NULL); 2914 NULL);
2900 2915 util_transmission_tk
2901 util_transmission_tk = GNUNET_SCHEDULER_add_delayed (UTIL_TRANSMISSION_INTERVAL, 2916 = GNUNET_SCHEDULER_add_delayed (UTIL_TRANSMISSION_INTERVAL,
2902 utilization_transmission, NULL); 2917 &utilization_transmission,
2903 2918 NULL);
2904} 2919}
2905 2920
2906 2921
@@ -3040,8 +3055,9 @@ master_task (void *cls,
3040 GNUNET_i2s (&n->id)); 3055 GNUNET_i2s (&n->id));
3041 /* Remove address and request and additional one */ 3056 /* Remove address and request and additional one */
3042 unset_primary_address (n); 3057 unset_primary_address (n);
3043 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_INIT_ATS, 3058 set_state_and_timeout (n,
3044 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT)); 3059 GNUNET_TRANSPORT_PS_INIT_ATS,
3060 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
3045 return; 3061 return;
3046 } 3062 }
3047 break; 3063 break;
@@ -3100,15 +3116,12 @@ master_task (void *cls,
3100 case GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT: 3116 case GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT:
3101 if (0 == delay.rel_value_us) 3117 if (0 == delay.rel_value_us)
3102 { 3118 {
3103 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 3119 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3104 "Connection to `%s' timed out, missing KEEPALIVE_RESPONSEs (after trying to SYN on alternative address)\n", 3120 "Switch failed, cleaning up alternative address\n");
3105 GNUNET_i2s (&n->id)); 3121 free_address (&n->alternative_address);
3106 GNUNET_STATISTICS_update (GST_stats, 3122 set_state_and_timeout (n,
3107 gettext_noop ("# Failed attempts to switch addresses (no response)"), 3123 GNUNET_TRANSPORT_PS_CONNECTED,
3108 1, 3124 GNUNET_TIME_relative_to_absolute (SETUP_CONNECTION_TIMEOUT));
3109 GNUNET_NO);
3110 disconnect_neighbour (n);
3111 return;
3112 } 3125 }
3113 try_transmission_to_peer (n); 3126 try_transmission_to_peer (n);
3114 send_keepalive (n); 3127 send_keepalive (n);
@@ -3130,6 +3143,7 @@ master_task (void *cls,
3130 GNUNET_break (0); 3143 GNUNET_break (0);
3131 break; 3144 break;
3132 } 3145 }
3146 delay = GNUNET_TIME_absolute_get_remaining (n->timeout);
3133 if ( (GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT == n->state) || 3147 if ( (GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT == n->state) ||
3134 (GNUNET_TRANSPORT_PS_CONNECTED == n->state) ) 3148 (GNUNET_TRANSPORT_PS_CONNECTED == n->state) )
3135 { 3149 {
@@ -3157,15 +3171,19 @@ send_session_ack_message (struct NeighbourMapEntry *n)
3157{ 3171{
3158 struct GNUNET_MessageHeader msg; 3172 struct GNUNET_MessageHeader msg;
3159 3173
3160 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Sending ACK message to peer `%s'\n", 3174 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3175 "Sending ACK message to peer `%s'\n",
3161 GNUNET_i2s (&n->id)); 3176 GNUNET_i2s (&n->id));
3162 3177
3163 msg.size = htons (sizeof (struct GNUNET_MessageHeader)); 3178 msg.size = htons (sizeof (struct GNUNET_MessageHeader));
3164 msg.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_ACK); 3179 msg.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_ACK);
3165 (void) send_with_session(n, 3180 (void) send_with_session (n,
3166 (const char *) &msg, sizeof (struct GNUNET_MessageHeader), 3181 &msg,
3167 UINT32_MAX, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_NO, 3182 sizeof (struct GNUNET_MessageHeader),
3168 NULL, NULL); 3183 UINT32_MAX,
3184 GNUNET_TIME_UNIT_FOREVER_REL,
3185 GNUNET_NO,
3186 NULL, NULL);
3169} 3187}
3170 3188
3171 3189
@@ -3173,7 +3191,7 @@ send_session_ack_message (struct NeighbourMapEntry *n)
3173 * We received a 'SESSION_SYN_ACK' message from the other peer. 3191 * We received a 'SESSION_SYN_ACK' message from the other peer.
3174 * Consider switching to it. 3192 * Consider switching to it.
3175 * 3193 *
3176 * @param message possibly a 'struct SessionConnectMessage' (check format) 3194 * @param message possibly a `struct SessionConnectMessage` (check format)
3177 * @param peer identity of the peer to switch the address for 3195 * @param peer identity of the peer to switch the address for
3178 * @param address address of the other peer, NULL if other peer 3196 * @param address address of the other peer, NULL if other peer
3179 * connected to us 3197 * connected to us
@@ -3189,10 +3207,6 @@ GST_neighbours_handle_session_syn_ack (const struct GNUNET_MessageHeader *messag
3189 struct GNUNET_TIME_Absolute ts; 3207 struct GNUNET_TIME_Absolute ts;
3190 struct NeighbourMapEntry *n; 3208 struct NeighbourMapEntry *n;
3191 3209
3192 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3193 "Received SYN_ACK message from peer `%s'\n",
3194 GNUNET_i2s (&address->peer));
3195
3196 if (ntohs (message->size) != sizeof (struct TransportSynMessage)) 3210 if (ntohs (message->size) != sizeof (struct TransportSynMessage))
3197 { 3211 {
3198 GNUNET_break_op (0); 3212 GNUNET_break_op (0);
@@ -3212,6 +3226,11 @@ GST_neighbours_handle_session_syn_ack (const struct GNUNET_MessageHeader *messag
3212 1, GNUNET_NO); 3226 1, GNUNET_NO);
3213 return GNUNET_SYSERR; 3227 return GNUNET_SYSERR;
3214 } 3228 }
3229 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3230 "Received SYN_ACK message from peer `%s' in state %s/%s\n",
3231 GNUNET_i2s (&address->peer),
3232 GNUNET_TRANSPORT_ps2s (n->state),
3233 print_ack_state (n->ack_state));
3215 ts = GNUNET_TIME_absolute_ntoh (scm->timestamp); 3234 ts = GNUNET_TIME_absolute_ntoh (scm->timestamp);
3216 switch (n->state) 3235 switch (n->state)
3217 { 3236 {
@@ -3221,9 +3240,9 @@ GST_neighbours_handle_session_syn_ack (const struct GNUNET_MessageHeader *messag
3221 return GNUNET_SYSERR; 3240 return GNUNET_SYSERR;
3222 case GNUNET_TRANSPORT_PS_INIT_ATS: 3241 case GNUNET_TRANSPORT_PS_INIT_ATS:
3223 GNUNET_STATISTICS_update (GST_stats, 3242 GNUNET_STATISTICS_update (GST_stats,
3224 gettext_noop 3243 gettext_noop ("# unexpected SYN_ACK messages (not ready)"),
3225 ("# unexpected SYN_ACK messages (not ready)"), 3244 1,
3226 1, GNUNET_NO); 3245 GNUNET_NO);
3227 break; 3246 break;
3228 case GNUNET_TRANSPORT_PS_SYN_SENT: 3247 case GNUNET_TRANSPORT_PS_SYN_SENT:
3229 if (ts.abs_value_us != n->primary_address.connect_timestamp.abs_value_us) 3248 if (ts.abs_value_us != n->primary_address.connect_timestamp.abs_value_us)
@@ -3232,16 +3251,9 @@ GST_neighbours_handle_session_syn_ack (const struct GNUNET_MessageHeader *messag
3232 "SYN_ACK ignored as the timestamp does not match our SYN request\n"); 3251 "SYN_ACK ignored as the timestamp does not match our SYN request\n");
3233 return GNUNET_OK; 3252 return GNUNET_OK;
3234 } 3253 }
3235 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECTED, 3254 set_state_and_timeout (n,
3236 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT)); 3255 GNUNET_TRANSPORT_PS_CONNECTED,
3237 GNUNET_STATISTICS_set (GST_stats, 3256 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
3238 gettext_noop ("# peers connected"),
3239 ++neighbours_connected,
3240 GNUNET_NO);
3241 neighbours_connect_notification (&n->id,
3242 n->primary_address.bandwidth_in,
3243 n->primary_address.bandwidth_out);
3244 /* Tell ATS that the outbound session we created to send SYN was successful */
3245 set_primary_address (n, 3257 set_primary_address (n,
3246 n->primary_address.address, 3258 n->primary_address.address,
3247 n->primary_address.session, 3259 n->primary_address.session,
@@ -3253,9 +3265,9 @@ GST_neighbours_handle_session_syn_ack (const struct GNUNET_MessageHeader *messag
3253 case GNUNET_TRANSPORT_PS_SYN_RECV_ATS: 3265 case GNUNET_TRANSPORT_PS_SYN_RECV_ATS:
3254 case GNUNET_TRANSPORT_PS_SYN_RECV_ACK: 3266 case GNUNET_TRANSPORT_PS_SYN_RECV_ACK:
3255 GNUNET_STATISTICS_update (GST_stats, 3267 GNUNET_STATISTICS_update (GST_stats,
3256 gettext_noop 3268 gettext_noop ("# unexpected SYN_ACK messages (not ready)"),
3257 ("# unexpected SYN_ACK messages (not ready)"), 3269 1,
3258 1, GNUNET_NO); 3270 GNUNET_NO);
3259 break; 3271 break;
3260 case GNUNET_TRANSPORT_PS_CONNECTED: 3272 case GNUNET_TRANSPORT_PS_CONNECTED:
3261 /* duplicate SYN_ACK, let's answer by duplicate ACK just in case */ 3273 /* duplicate SYN_ACK, let's answer by duplicate ACK just in case */
@@ -3265,30 +3277,40 @@ GST_neighbours_handle_session_syn_ack (const struct GNUNET_MessageHeader *messag
3265 /* we didn't expect any SYN_ACK, as we are waiting for ATS 3277 /* we didn't expect any SYN_ACK, as we are waiting for ATS
3266 to give us a new address... */ 3278 to give us a new address... */
3267 GNUNET_STATISTICS_update (GST_stats, 3279 GNUNET_STATISTICS_update (GST_stats,
3268 gettext_noop 3280 gettext_noop ("# unexpected SYN_ACK messages (waiting on ATS)"),
3269 ("# unexpected SYN_ACK messages (waiting on ATS)"), 3281 1,
3270 1, GNUNET_NO); 3282 GNUNET_NO);
3271 break; 3283 break;
3272 case GNUNET_TRANSPORT_PS_RECONNECT_SENT: 3284 case GNUNET_TRANSPORT_PS_RECONNECT_SENT:
3273 /* Reconnecting with new address address worked; go back to connected! */ 3285 /* Reconnecting with new address address worked; go back to connected! */
3274 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECTED, 3286 set_state_and_timeout (n,
3275 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT)); 3287 GNUNET_TRANSPORT_PS_CONNECTED,
3288 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
3276 send_session_ack_message (n); 3289 send_session_ack_message (n);
3277 break; 3290 break;
3278 case GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT: 3291 case GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT:
3279 /* new address worked; adopt it and go back to connected! */ 3292 /* new address worked; adopt it and go back to connected! */
3280 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECTED, 3293 set_state_and_timeout (n,
3294 GNUNET_TRANSPORT_PS_CONNECTED,
3281 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT)); 3295 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
3282 GNUNET_break (GNUNET_NO == n->alternative_address.ats_active); 3296 GNUNET_break (GNUNET_NO == n->alternative_address.ats_active);
3283 3297
3284 /* Set primary addresses */ 3298 /* Set primary addresses */
3285 set_primary_address (n, n->alternative_address.address, 3299 set_primary_address (n,
3286 n->alternative_address.session, n->alternative_address.bandwidth_in, 3300 n->alternative_address.address,
3287 n->alternative_address.bandwidth_out, GNUNET_YES); 3301 n->alternative_address.session,
3288 GNUNET_STATISTICS_update (GST_stats, gettext_noop 3302 n->alternative_address.bandwidth_in,
3289 ("# Successful attempts to switch addresses"), 1, GNUNET_NO); 3303 n->alternative_address.bandwidth_out,
3304 GNUNET_YES);
3305 GNUNET_STATISTICS_update (GST_stats,
3306 gettext_noop ("# Successful attempts to switch addresses"),
3307 1,
3308 GNUNET_NO);
3290 3309
3291 free_address (&n->alternative_address); 3310 GNUNET_HELLO_address_free (n->alternative_address.address);
3311 memset (&n->alternative_address,
3312 0,
3313 sizeof (n->alternative_address));
3292 send_session_ack_message (n); 3314 send_session_ack_message (n);
3293 break; 3315 break;
3294 case GNUNET_TRANSPORT_PS_DISCONNECT: 3316 case GNUNET_TRANSPORT_PS_DISCONNECT:
@@ -3351,8 +3373,12 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer,
3351 /* Free alternative address */ 3373 /* Free alternative address */
3352 if (session == n->alternative_address.session) 3374 if (session == n->alternative_address.session)
3353 { 3375 {
3354 if ( (GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT == n->state) ) 3376 if (GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT == n->state)
3355 set_state (n, GNUNET_TRANSPORT_PS_CONNECTED); 3377 set_state_and_timeout (n,
3378 GNUNET_TRANSPORT_PS_CONNECTED,
3379 n->timeout);
3380 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3381 "Session died, cleaning up alternative address\n");
3356 free_address (&n->alternative_address); 3382 free_address (&n->alternative_address);
3357 } 3383 }
3358 return GNUNET_NO; /* doesn't affect us further */ 3384 return GNUNET_NO; /* doesn't affect us further */
@@ -3382,20 +3408,21 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer,
3382 3408
3383 /* Destroy the address since it cannot be used */ 3409 /* Destroy the address since it cannot be used */
3384 unset_primary_address (n); 3410 unset_primary_address (n);
3385 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_INIT_ATS, 3411 set_state_and_timeout (n,
3386 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT)); 3412 GNUNET_TRANSPORT_PS_INIT_ATS,
3413 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
3387 break; 3414 break;
3388 case GNUNET_TRANSPORT_PS_SYN_RECV_ATS: 3415 case GNUNET_TRANSPORT_PS_SYN_RECV_ATS:
3389 case GNUNET_TRANSPORT_PS_SYN_RECV_ACK: 3416 case GNUNET_TRANSPORT_PS_SYN_RECV_ACK:
3390 /* error on inbound session; free neighbour entirely */ 3417 /* error on inbound session; free neighbour entirely */
3391 free_address (&n->primary_address);
3392 free_neighbour (n); 3418 free_neighbour (n);
3393 return GNUNET_YES; 3419 return GNUNET_YES;
3394 case GNUNET_TRANSPORT_PS_CONNECTED: 3420 case GNUNET_TRANSPORT_PS_CONNECTED:
3395 /* Our primary connection died, try a fast reconnect */ 3421 /* Our primary connection died, try a fast reconnect */
3396 unset_primary_address (n); 3422 unset_primary_address (n);
3397 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_RECONNECT_ATS, 3423 set_state_and_timeout (n,
3398 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT)); 3424 GNUNET_TRANSPORT_PS_RECONNECT_ATS,
3425 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
3399 break; 3426 break;
3400 case GNUNET_TRANSPORT_PS_RECONNECT_ATS: 3427 case GNUNET_TRANSPORT_PS_RECONNECT_ATS:
3401 /* we don't have an address, how can it go down? */ 3428 /* we don't have an address, how can it go down? */
@@ -3410,36 +3437,39 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer,
3410 GNUNET_i2s (peer)); 3437 GNUNET_i2s (peer));
3411 /* Destroy the address since it cannot be used */ 3438 /* Destroy the address since it cannot be used */
3412 unset_primary_address (n); 3439 unset_primary_address (n);
3413 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_RECONNECT_ATS, 3440 set_state_and_timeout (n,
3414 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT)); 3441 GNUNET_TRANSPORT_PS_RECONNECT_ATS,
3442 GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT));
3415 break; 3443 break;
3416 case GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT: 3444 case GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT:
3417 /* primary went down while we were waiting for SYN_ACK on secondary; 3445 /* primary went down while we were waiting for SYN_ACK on secondary;
3418 secondary as primary */ 3446 secondary as primary */
3419 3447
3420 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 3448 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3421 "Connection `%s' %p to peer `%s' was terminated while switching, " 3449 "Connection `%s' %p to peer `%s' was terminated while switching, "
3422 "switching to alternative address `%s' %p\n", 3450 "switching to alternative address `%s' %p\n",
3423 GST_plugins_a2s (n->primary_address.address), 3451 GST_plugins_a2s (n->primary_address.address),
3424 n->primary_address.session, 3452 n->primary_address.session,
3425 GNUNET_i2s (peer), 3453 GNUNET_i2s (peer),
3426 GST_plugins_a2s (n->alternative_address.address), 3454 GST_plugins_a2s (n->alternative_address.address),
3427 n->alternative_address.session); 3455 n->alternative_address.session);
3428 3456
3429 /* Destroy the inbound address since it cannot be used */ 3457 /* Destroy the inbound address since it cannot be used */
3430 free_address (&n->primary_address); 3458 free_address (&n->primary_address);
3431 n->primary_address = n->alternative_address; 3459 n->primary_address = n->alternative_address;
3432 memset (&n->alternative_address, 0, sizeof (struct NeighbourAddress)); 3460 memset (&n->alternative_address,
3433 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_RECONNECT_SENT, 3461 0,
3434 GNUNET_TIME_relative_to_absolute (FAST_RECONNECT_TIMEOUT)); 3462 sizeof (struct NeighbourAddress));
3463 set_state_and_timeout (n,
3464 GNUNET_TRANSPORT_PS_RECONNECT_SENT,
3465 GNUNET_TIME_relative_to_absolute (FAST_RECONNECT_TIMEOUT));
3435 break; 3466 break;
3436 case GNUNET_TRANSPORT_PS_DISCONNECT: 3467 case GNUNET_TRANSPORT_PS_DISCONNECT:
3437 free_address (&n->primary_address); 3468 unset_primary_address (n);
3438 break; 3469 break;
3439 case GNUNET_TRANSPORT_PS_DISCONNECT_FINISHED: 3470 case GNUNET_TRANSPORT_PS_DISCONNECT_FINISHED:
3440 /* neighbour was freed and plugins told to terminate session */ 3471 /* neighbour was freed and plugins told to terminate session */
3441 return GNUNET_NO; 3472 return GNUNET_NO;
3442 break;
3443 default: 3473 default:
3444 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 3474 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3445 "Unhandled state `%s'\n", 3475 "Unhandled state `%s'\n",
@@ -3471,9 +3501,6 @@ GST_neighbours_handle_session_ack (const struct GNUNET_MessageHeader *message,
3471{ 3501{
3472 struct NeighbourMapEntry *n; 3502 struct NeighbourMapEntry *n;
3473 3503
3474 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3475 "Received ACK message from peer `%s'\n",
3476 GNUNET_i2s (&address->peer));
3477 if (ntohs (message->size) != sizeof (struct GNUNET_MessageHeader)) 3504 if (ntohs (message->size) != sizeof (struct GNUNET_MessageHeader))
3478 { 3505 {
3479 GNUNET_break_op (0); 3506 GNUNET_break_op (0);
@@ -3488,10 +3515,8 @@ GST_neighbours_handle_session_ack (const struct GNUNET_MessageHeader *message,
3488 GNUNET_break_op (0); 3515 GNUNET_break_op (0);
3489 return GNUNET_SYSERR; 3516 return GNUNET_SYSERR;
3490 } 3517 }
3491 3518 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3492 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 3519 "Received ACK for peer `%s' in state %s/%s\n",
3493 "Received %s for peer `%s' in state %s/%s\n",
3494 "ACK",
3495 GNUNET_i2s (&address->peer), 3520 GNUNET_i2s (&address->peer),
3496 GNUNET_TRANSPORT_ps2s (n->state), 3521 GNUNET_TRANSPORT_ps2s (n->state),
3497 print_ack_state (n->ack_state)); 3522 print_ack_state (n->ack_state));
@@ -3521,20 +3546,6 @@ GST_neighbours_handle_session_ack (const struct GNUNET_MessageHeader *message,
3521 GNUNET_NO); 3546 GNUNET_NO);
3522 return GNUNET_OK; 3547 return GNUNET_OK;
3523 } 3548 }
3524
3525 /* We are connected */
3526 if (GNUNET_NO == GST_neighbours_test_connected(&n->id))
3527 {
3528 /* Notify about connection */
3529 neighbours_connect_notification (&n->id,
3530 n->primary_address.bandwidth_in,
3531 n->primary_address.bandwidth_out);
3532 GNUNET_STATISTICS_set (GST_stats,
3533 gettext_noop ("# peers connected"),
3534 ++neighbours_connected,
3535 GNUNET_NO);
3536 }
3537
3538 if (GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT == n->state) 3549 if (GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT == n->state)
3539 { 3550 {
3540 /* We tried to switch addresses while being connect. We explicitly wait 3551 /* We tried to switch addresses while being connect. We explicitly wait
@@ -3542,9 +3553,9 @@ GST_neighbours_handle_session_ack (const struct GNUNET_MessageHeader *message,
3542 * so we do not want to set the address as in use! */ 3553 * so we do not want to set the address as in use! */
3543 return GNUNET_OK; 3554 return GNUNET_OK;
3544 } 3555 }
3545 3556 set_state_and_timeout (n,
3546 set_state_and_timeout (n, GNUNET_TRANSPORT_PS_CONNECTED, 3557 GNUNET_TRANSPORT_PS_CONNECTED,
3547 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT)); 3558 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
3548 3559
3549 /* Set primary address to used */ 3560 /* Set primary address to used */
3550 set_primary_address (n, 3561 set_primary_address (n,
@@ -3880,7 +3891,7 @@ GST_neighbours_stop ()
3880 &disconnect_all_neighbours, 3891 &disconnect_all_neighbours,
3881 NULL); 3892 NULL);
3882 GNUNET_CONTAINER_multipeermap_destroy (neighbours); 3893 GNUNET_CONTAINER_multipeermap_destroy (neighbours);
3883 3894 neighbours = NULL;
3884 next = pending_bc_head; 3895 next = pending_bc_head;
3885 for (cur = next; NULL != cur; cur = next) 3896 for (cur = next; NULL != cur; cur = next)
3886 { 3897 {
@@ -3898,7 +3909,6 @@ GST_neighbours_stop ()
3898 GNUNET_HELLO_address_free (cur->address); 3909 GNUNET_HELLO_address_free (cur->address);
3899 GNUNET_free (cur); 3910 GNUNET_free (cur);
3900 } 3911 }
3901 neighbours = NULL;
3902} 3912}
3903 3913
3904 3914