aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2011-10-26 09:21:18 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2011-10-26 09:21:18 +0000
commit2b500f19f324c22cbedbaecaa2763bc781711730 (patch)
tree64635111e3aeabe91c4952ff67111052f0ca8a27 /src/transport
parent70eaa3dda652deed20a9ec5ff228a5620db0016e (diff)
downloadgnunet-2b500f19f324c22cbedbaecaa2763bc781711730.tar.gz
gnunet-2b500f19f324c22cbedbaecaa2763bc781711730.zip
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/gnunet-service-transport_neighbours_fsm.c289
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
342static int 343static int
344is_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
351static int
352is_connected (struct NeighbourMapEntry * n)
353{
354 if (n->state == S_CONNECTED)
355 return GNUNET_YES;
356 return GNUNET_NO;
357}
358
359static int
360is_disconnecting (struct NeighbourMapEntry * n)
361{
362 if (n->state == S_DISCONNECT)
363 return GNUNET_YES;
364 return GNUNET_NO;
365}
366
367static int
343change (struct NeighbourMapEntry * n, int state, int line) 368change (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
475static ssize_t
476send_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 */
780static void 855static void
781send_connect_continuation (void *cls, 856send_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
1411static void
1412send_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
1338GST_neighbours_force_disconnect (const struct GNUNET_PeerIdentity *target) 1450GST_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,