aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2011-10-27 13:01:11 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2011-10-27 13:01:11 +0000
commit64d5a91798af32dd3a5183ee5e9ddafcbc376ead (patch)
treed056f24147f6a92453556a1789df2178d0f9b6fc /src/transport
parent19780f69c439907bbe4d35265ac1b7ad092c50cd (diff)
downloadgnunet-64d5a91798af32dd3a5183ee5e9ddafcbc376ead.tar.gz
gnunet-64d5a91798af32dd3a5183ee5e9ddafcbc376ead.zip
more changes:
including connection switching
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/gnunet-service-transport_neighbours_fsm.c325
1 files changed, 191 insertions, 134 deletions
diff --git a/src/transport/gnunet-service-transport_neighbours_fsm.c b/src/transport/gnunet-service-transport_neighbours_fsm.c
index e920580a9..862608004 100644
--- a/src/transport/gnunet-service-transport_neighbours_fsm.c
+++ b/src/transport/gnunet-service-transport_neighbours_fsm.c
@@ -365,59 +365,40 @@ is_disconnecting (struct NeighbourMapEntry * n)
365 return GNUNET_NO; 365 return GNUNET_NO;
366} 366}
367 367
368static int 368static const char *
369change (struct NeighbourMapEntry * n, int state, int line) 369print_state (int state)
370{ 370{
371 char * old = NULL;
372 char * new = NULL;
373
374 switch (n->state) {
375 case S_CONNECTED:
376 old = "S_CONNECTED";
377 break;
378 case S_CONNECT_RECV:
379 old = "S_CONNECT_RECV";
380 break;
381 case S_CONNECT_RECV_ACK_SENT:
382 old = "S_CONNECT_RECV_ACK_SENT";
383 break;
384 case S_CONNECT_SENT:
385 old = "S_CONNECT_SENT";
386 break;
387 case S_DISCONNECT:
388 old = "S_DISCONNECT";
389 break;
390 case S_NOT_CONNECTED:
391 old = "S_NOT_CONNECTED";
392 break;
393 default:
394 GNUNET_break (0);
395 break;
396 }
397
398 switch (state) { 371 switch (state) {
399 case S_CONNECTED: 372 case S_CONNECTED:
400 new = "S_CONNECTED"; 373 return "S_CONNECTED";
401 break; 374 break;
402 case S_CONNECT_RECV: 375 case S_CONNECT_RECV:
403 new = "S_CONNECT_RECV"; 376 return "S_CONNECT_RECV";
404 break; 377 break;
405 case S_CONNECT_RECV_ACK_SENT: 378 case S_CONNECT_RECV_ACK_SENT:
406 new = "S_CONNECT_RECV_ACK_SENT"; 379 return"S_CONNECT_RECV_ACK_SENT";
407 break; 380 break;
408 case S_CONNECT_SENT: 381 case S_CONNECT_SENT:
409 new = "S_CONNECT_SENT"; 382 return "S_CONNECT_SENT";
410 break; 383 break;
411 case S_DISCONNECT: 384 case S_DISCONNECT:
412 new = "S_DISCONNECT"; 385 return "S_DISCONNECT";
413 break; 386 break;
414 case S_NOT_CONNECTED: 387 case S_NOT_CONNECTED:
415 new = "S_NOT_CONNECTED"; 388 return "S_NOT_CONNECTED";
416 break; 389 break;
417 default: 390 default:
418 GNUNET_break (0); 391 GNUNET_break (0);
419 break; 392 break;
420 } 393 }
394 return NULL;
395}
396
397static int
398change (struct NeighbourMapEntry * n, int state, int line)
399{
400 char * old = strdup(print_state(n->state));
401 char * new = strdup(print_state(state));
421 402
422 /* allowed transitions */ 403 /* allowed transitions */
423 int allowed = GNUNET_NO; 404 int allowed = GNUNET_NO;
@@ -471,18 +452,21 @@ change (struct NeighbourMapEntry * n, int state, int line)
471 "Illegal state transition from `%s' to `%s' in line %u \n", 452 "Illegal state transition from `%s' to `%s' in line %u \n",
472 old, new, line); 453 old, new, line);
473 GNUNET_break (0); 454 GNUNET_break (0);
455 GNUNET_free (old);
456 GNUNET_free (new);
474 return GNUNET_SYSERR; 457 return GNUNET_SYSERR;
475 } 458 }
476 459
477 n->state = state; 460 n->state = state;
478 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "State for neighbour `%s' %X changed from `%s' to `%s' in line %u\n", 461 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "State for neighbour `%s' %X changed from `%s' to `%s' in line %u\n",
479 GNUNET_i2s (&n->id), n, old, new, line); 462 GNUNET_i2s (&n->id), n, old, new, line);
463 GNUNET_free (old);
464 GNUNET_free (new);
480 return GNUNET_OK; 465 return GNUNET_OK;
481} 466}
482 467
483static ssize_t 468static ssize_t
484send_with_plugin (void *cls, 469send_with_plugin ( const struct GNUNET_PeerIdentity * target,
485 const struct GNUNET_PeerIdentity * target,
486 const char *msgbuf, 470 const char *msgbuf,
487 size_t msgbuf_size, 471 size_t msgbuf_size,
488 uint32_t priority, 472 uint32_t priority,
@@ -584,7 +568,6 @@ try_transmission_to_peer (struct NeighbourMapEntry *n)
584 struct MessageQueue *mq; 568 struct MessageQueue *mq;
585 struct GNUNET_TIME_Relative timeout; 569 struct GNUNET_TIME_Relative timeout;
586 ssize_t ret; 570 ssize_t ret;
587 struct GNUNET_TRANSPORT_PluginFunctions *papi;
588 571
589 if (n->is_active != NULL) 572 if (n->is_active != NULL)
590 { 573 {
@@ -609,8 +592,7 @@ try_transmission_to_peer (struct NeighbourMapEntry *n)
609 if (NULL == mq) 592 if (NULL == mq)
610 return; /* no more messages */ 593 return; /* no more messages */
611 594
612 papi = GST_plugins_find (n->plugin_name); 595 if (GST_plugins_find (n->plugin_name) == NULL)
613 if (papi == NULL)
614 { 596 {
615 GNUNET_break (0); 597 GNUNET_break (0);
616 return; 598 return;
@@ -628,13 +610,13 @@ try_transmission_to_peer (struct NeighbourMapEntry *n)
628 n->transmission_task = GNUNET_SCHEDULER_add_now (&transmission_task, n); 610 n->transmission_task = GNUNET_SCHEDULER_add_now (&transmission_task, n);
629 return; 611 return;
630 } 612 }
631 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "try_transmission_to_peer\n"); 613
632 papi = GST_plugins_find (n->plugin_name); 614 ret = send_with_plugin (&n->id,
633 ret = 615 mq->message_buf, mq->message_buf_size, 0,
634 papi->send (papi->cls, &n->id, mq->message_buf, mq->message_buf_size, 616 timeout,
635 0 /* priority -- remove from plugin API? */ , 617 n->session, n->plugin_name, n->addr, n->addrlen,
636 timeout, n->session, n->addr, n->addrlen, GNUNET_YES, 618 GNUNET_YES,
637 &transmit_send_continuation, mq); 619 &transmit_send_continuation, mq);
638 if (ret == -1) 620 if (ret == -1)
639 { 621 {
640 /* failure, but 'send' would not call continuation in this case, 622 /* failure, but 'send' would not call continuation in this case,
@@ -654,7 +636,6 @@ try_transmission_to_peer (struct NeighbourMapEntry *n)
654static void 636static void
655transmission_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 637transmission_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
656{ 638{
657 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "transmission_task\n");
658 struct NeighbourMapEntry *n = cls; 639 struct NeighbourMapEntry *n = cls;
659 GNUNET_assert (NULL != lookup_neighbour(&n->id)); 640 GNUNET_assert (NULL != lookup_neighbour(&n->id));
660 n->transmission_task = GNUNET_SCHEDULER_NO_TASK; 641 n->transmission_task = GNUNET_SCHEDULER_NO_TASK;
@@ -679,6 +660,18 @@ GST_neighbours_start (void *cls, GNUNET_TRANSPORT_NotifyConnect connect_cb,
679 neighbours = GNUNET_CONTAINER_multihashmap_create (NEIGHBOUR_TABLE_SIZE); 660 neighbours = GNUNET_CONTAINER_multihashmap_create (NEIGHBOUR_TABLE_SIZE);
680} 661}
681 662
663static void
664send_disconnect_cont (void *cls,
665 const struct GNUNET_PeerIdentity * target,
666 int result)
667{
668 struct NeighbourMapEntry *n = cls;
669
670 if (result == GNUNET_OK)
671 change_state (n, S_DISCONNECT);
672 else
673 change_state (n, S_NOT_CONNECTED);
674}
682 675
683static int 676static int
684send_disconnect (struct NeighbourMapEntry *n) 677send_disconnect (struct NeighbourMapEntry *n)
@@ -703,10 +696,10 @@ send_disconnect (struct NeighbourMapEntry *n)
703 &disconnect_msg.purpose, 696 &disconnect_msg.purpose,
704 &disconnect_msg.signature)); 697 &disconnect_msg.signature));
705 698
706 ret = send_with_plugin(NULL, &n->id, 699 ret = send_with_plugin(&n->id,
707 (const char *) &disconnect_msg, sizeof (disconnect_msg), 700 (const char *) &disconnect_msg, sizeof (disconnect_msg),
708 UINT32_MAX, GNUNET_TIME_UNIT_FOREVER_REL, n->session, n->plugin_name, n->addr, n->addrlen, 701 UINT32_MAX, GNUNET_TIME_UNIT_FOREVER_REL, n->session, n->plugin_name, n->addr, n->addrlen,
709 GNUNET_YES, NULL, n); 702 GNUNET_YES, &send_disconnect_cont, n);
710 703
711 if (ret == GNUNET_SYSERR) 704 if (ret == GNUNET_SYSERR)
712 return GNUNET_SYSERR; 705 return GNUNET_SYSERR;
@@ -738,13 +731,11 @@ disconnect_neighbour (struct NeighbourMapEntry *n)
738 { 731 {
739 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Sent DISCONNECT_MSG to `%s'\n", 732 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Sent DISCONNECT_MSG to `%s'\n",
740 GNUNET_i2s (&n->id)); 733 GNUNET_i2s (&n->id));
741 change_state (n, S_DISCONNECT);
742 } 734 }
743 else 735 else
744 { 736 {
745 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not send DISCONNECT_MSG to `%s'\n", 737 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not send DISCONNECT_MSG to `%s'\n",
746 GNUNET_i2s (&n->id)); 738 GNUNET_i2s (&n->id));
747 change_state (n, S_NOT_CONNECTED);
748 } 739 }
749 } 740 }
750 741
@@ -851,7 +842,7 @@ neighbour_keepalive_task (void *cls,
851 m.size = htons (sizeof (struct GNUNET_MessageHeader)); 842 m.size = htons (sizeof (struct GNUNET_MessageHeader));
852 m.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE); 843 m.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE);
853 844
854 send_with_plugin(NULL, &n->id, (const void *) &m, 845 send_with_plugin(&n->id, (const void *) &m,
855 sizeof (m), 846 sizeof (m),
856 UINT32_MAX /* priority */ , 847 UINT32_MAX /* priority */ ,
857 GNUNET_TIME_UNIT_FOREVER_REL, 848 GNUNET_TIME_UNIT_FOREVER_REL,
@@ -921,6 +912,8 @@ send_connect_continuation (void *cls,
921 struct NeighbourMapEntry *n = cls; 912 struct NeighbourMapEntry *n = cls;
922 913
923 GNUNET_assert (n != NULL); 914 GNUNET_assert (n != NULL);
915 GNUNET_assert (!is_connected(n));
916
924 if (GNUNET_YES == n->in_disconnect) 917 if (GNUNET_YES == n->in_disconnect)
925 return; /* neighbour is going away */ 918 return; /* neighbour is going away */
926 if (GNUNET_YES != success) 919 if (GNUNET_YES != success)
@@ -934,7 +927,6 @@ send_connect_continuation (void *cls,
934 n->addrlen), 927 n->addrlen),
935 n->session); 928 n->session);
936#endif 929#endif
937 change_state(n, S_NOT_CONNECTED);
938 930
939 GNUNET_ATS_address_destroyed (GST_ats, 931 GNUNET_ATS_address_destroyed (GST_ats,
940 &n->id, 932 &n->id,
@@ -949,6 +941,52 @@ send_connect_continuation (void *cls,
949 change_state(n, S_CONNECT_SENT); 941 change_state(n, S_CONNECT_SENT);
950} 942}
951 943
944
945/**
946 * We tried to switch addresses with an peer already connected. If it failed,
947 * we should tell ATS to not use this address anymore (until it is re-validated).
948 *
949 * @param cls the 'struct NeighbourMapEntry'
950 * @param success GNUNET_OK on success
951 */
952static void
953send_switch_address_continuation (void *cls,
954 const struct GNUNET_PeerIdentity * target,
955 int success)
956
957{
958 struct NeighbourMapEntry *n = cls;
959
960 GNUNET_assert (n != NULL);
961 if (GNUNET_YES == n->in_disconnect)
962 return; /* neighbour is going away */
963
964 GNUNET_assert (n->state == S_CONNECTED);
965 if (GNUNET_YES != success)
966 {
967#if DEBUG_TRANSPORT
968 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
969 "Failed to send CONNECT_MSG to peer `%4s' with plugin `%s' address '%s' session %X, asking ATS for new address \n",
970 GNUNET_i2s (&n->id), n->plugin_name,
971 (n->addrlen == 0) ? "<inbound>" : GST_plugins_a2s (n->plugin_name,
972 n->addr,
973 n->addrlen),
974 n->session);
975#endif
976 change_state(n, S_NOT_CONNECTED);
977
978 GNUNET_ATS_address_destroyed (GST_ats,
979 &n->id,
980 n->plugin_name,
981 n->addr,
982 n->addrlen,
983 NULL);
984
985 GNUNET_ATS_suggest_address(GST_ats, &n->id);
986 return;
987 }
988}
989
952/** 990/**
953 * We tried to send a SESSION_CONNECT message to another peer. If this 991 * We tried to send a SESSION_CONNECT message to another peer. If this
954 * succeeded, we change the state. If it failed, we should tell 992 * succeeded, we change the state. If it failed, we should tell
@@ -965,11 +1003,6 @@ send_connect_ack_continuation (void *cls,
965{ 1003{
966 struct NeighbourMapEntry *n = cls; 1004 struct NeighbourMapEntry *n = cls;
967 1005
968 //FIMXE comeplete this
969 GNUNET_break (0);
970return;
971
972
973 GNUNET_assert (n != NULL); 1006 GNUNET_assert (n != NULL);
974 if (GNUNET_YES == n->in_disconnect) 1007 if (GNUNET_YES == n->in_disconnect)
975 return; /* neighbour is going away */ 1008 return; /* neighbour is going away */
@@ -996,7 +1029,7 @@ return;
996 GNUNET_ATS_suggest_address(GST_ats, &n->id); 1029 GNUNET_ATS_suggest_address(GST_ats, &n->id);
997 return; 1030 return;
998 } 1031 }
999 change_state(n, S_CONNECT_SENT); 1032 //change_state(n, S_CONNECT_SENT);
1000} 1033}
1001 1034
1002/** 1035/**
@@ -1026,14 +1059,6 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
1026 size_t msg_len; 1059 size_t msg_len;
1027 size_t ret; 1060 size_t ret;
1028 1061
1029 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1030 "SWITCH! Peer `%4s' switches to plugin `%s' address '%s' session %X\n",
1031 GNUNET_i2s (peer), plugin_name,
1032 (address_len == 0) ? "<inbound>" : GST_plugins_a2s (plugin_name,
1033 address,
1034 address_len),
1035 session);
1036
1037 GNUNET_assert (neighbours != NULL); 1062 GNUNET_assert (neighbours != NULL);
1038 n = lookup_neighbour (peer); 1063 n = lookup_neighbour (peer);
1039 if (NULL == n) 1064 if (NULL == n)
@@ -1046,16 +1071,17 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
1046 return GNUNET_NO; 1071 return GNUNET_NO;
1047 } 1072 }
1048 1073
1049
1050#if DEBUG_TRANSPORT 1074#if DEBUG_TRANSPORT
1051 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1075#endif
1052 "SWITCH! Peer `%4s' switches to plugin `%s' address '%s' session %X\n", 1076 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1053 GNUNET_i2s (peer), plugin_name, 1077 "ATS tells us to switch to plugin `%s' address '%s' session %X for %s peer `%s'\n",
1078 plugin_name,
1054 (address_len == 0) ? "<inbound>" : GST_plugins_a2s (plugin_name, 1079 (address_len == 0) ? "<inbound>" : GST_plugins_a2s (plugin_name,
1055 address, 1080 address,
1056 address_len), 1081 address_len),
1057 session); 1082 session, (is_connected(n) ? "CONNECTED" : "NOT CONNECTED"),
1058#endif 1083 GNUNET_i2s (peer));
1084
1059 GNUNET_free_non_null (n->addr); 1085 GNUNET_free_non_null (n->addr);
1060 n->addr = GNUNET_malloc (address_len); 1086 n->addr = GNUNET_malloc (address_len);
1061 memcpy (n->addr, address, address_len); 1087 memcpy (n->addr, address, address_len);
@@ -1079,7 +1105,7 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
1079 connect_msg.timestamp = 1105 connect_msg.timestamp =
1080 GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); 1106 GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
1081 1107
1082 ret =send_with_plugin (NULL, peer, (const char *) &connect_msg, msg_len, 0, GNUNET_TIME_UNIT_FOREVER_REL, session, plugin_name, address, address_len, GNUNET_YES, &send_connect_continuation, n); 1108 ret = send_with_plugin (peer, (const char *) &connect_msg, msg_len, 0, GNUNET_TIME_UNIT_FOREVER_REL, session, plugin_name, address, address_len, GNUNET_YES, &send_connect_continuation, n);
1083 if (ret == GNUNET_SYSERR) 1109 if (ret == GNUNET_SYSERR)
1084 { 1110 {
1085 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1111 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1090,7 +1116,9 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
1090 address_len), 1116 address_len),
1091 session); 1117 session);
1092 } 1118 }
1119 return GNUNET_NO;
1093 } 1120 }
1121 /* We received a CONNECT message and asked ATS for an address */
1094 else if (n->state == S_CONNECT_RECV) 1122 else if (n->state == S_CONNECT_RECV)
1095 { 1123 {
1096 msg_len = sizeof (struct SessionConnectMessage); 1124 msg_len = sizeof (struct SessionConnectMessage);
@@ -1100,22 +1128,41 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer,
1100 connect_msg.reserved = htonl (0); 1128 connect_msg.reserved = htonl (0);
1101 connect_msg.timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); 1129 connect_msg.timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
1102 1130
1103 ret = send_with_plugin(NULL, &n->id, (const void *) &connect_msg, msg_len, 0, GNUNET_TIME_UNIT_FOREVER_REL, session, plugin_name, address, address_len, GNUNET_YES, &send_connect_ack_continuation, n); 1131 ret = send_with_plugin(&n->id, (const void *) &connect_msg, msg_len, 0, GNUNET_TIME_UNIT_FOREVER_REL, session, plugin_name, address, address_len, GNUNET_YES, &send_connect_ack_continuation, n);
1104 if (ret == GNUNET_SYSERR) 1132 if (ret == GNUNET_SYSERR)
1105 { 1133 {
1106 change_state (n, S_NOT_CONNECTED); 1134 change_state (n, S_NOT_CONNECTED);
1107 GNUNET_break (0); 1135 GNUNET_break (0);
1108 return GNUNET_NO;
1109 } 1136 }
1137 return GNUNET_NO;
1110 } 1138 }
1111 else 1139 /* connected peer is switching addresses */
1140 else if (n->state == S_CONNECTED)
1112 { 1141 {
1113 GNUNET_break (0); 1142 msg_len = sizeof (struct SessionConnectMessage);
1114 } 1143 connect_msg.header.size = htons (msg_len);
1115 1144 connect_msg.header.type =
1116 1145 htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_CONNECT);
1146 connect_msg.reserved = htonl (0);
1147 connect_msg.timestamp =
1148 GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
1117 1149
1150 ret = send_with_plugin (peer, (const char *) &connect_msg, msg_len, 0, GNUNET_TIME_UNIT_FOREVER_REL, session, plugin_name, address, address_len, GNUNET_YES, &send_switch_address_continuation, n);
1151 if (ret == GNUNET_SYSERR)
1152 {
1153 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1154 "Failed to send CONNECT_MESSAGE to `%4s' using plugin `%s' address '%s' session %X\n",
1155 GNUNET_i2s (peer), plugin_name,
1156 (address_len == 0) ? "<inbound>" : GST_plugins_a2s (plugin_name,
1157 address,
1158 address_len),
1159 session);
1160 }
1161 return GNUNET_NO;
1162 }
1118 1163
1164 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Invalid connection state to switch addresses ");
1165 GNUNET_break (0);
1119 return GNUNET_NO; 1166 return GNUNET_NO;
1120} 1167}
1121 1168
@@ -1222,10 +1269,11 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer,
1222 GNUNET_assert (neighbours != NULL); 1269 GNUNET_assert (neighbours != NULL);
1223 1270
1224#if DEBUG_TRANSPORT 1271#if DEBUG_TRANSPORT
1225 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1272#endif
1273 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1226 "Session %X to peer `%s' ended \n", 1274 "Session %X to peer `%s' ended \n",
1227 session, GNUNET_i2s (peer)); 1275 session, GNUNET_i2s (peer));
1228#endif 1276
1229 n = lookup_neighbour (peer); 1277 n = lookup_neighbour (peer);
1230 if (NULL == n) 1278 if (NULL == n)
1231 return; 1279 return;
@@ -1246,6 +1294,7 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer,
1246 GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_DISCONNECT_SESSION_TIMEOUT, 1294 GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_DISCONNECT_SESSION_TIMEOUT,
1247 &neighbour_timeout_task, n); 1295 &neighbour_timeout_task, n);
1248 /* try QUICKLY to re-establish a connection, reduce timeout! */ 1296 /* try QUICKLY to re-establish a connection, reduce timeout! */
1297// change_state (n, S_NOT_CONNECTED);
1249 GNUNET_ATS_suggest_address (GST_ats, peer); 1298 GNUNET_ATS_suggest_address (GST_ats, peer);
1250} 1299}
1251 1300
@@ -1267,7 +1316,7 @@ GST_neighbours_send (const struct GNUNET_PeerIdentity *target, const void *msg,
1267{ 1316{
1268 struct NeighbourMapEntry *n; 1317 struct NeighbourMapEntry *n;
1269 struct MessageQueue *mq; 1318 struct MessageQueue *mq;
1270 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "GST_neighbours_send %u\n", __LINE__); 1319
1271 GNUNET_assert (neighbours != NULL); 1320 GNUNET_assert (neighbours != NULL);
1272 1321
1273 n = lookup_neighbour (target); 1322 n = lookup_neighbour (target);
@@ -1291,7 +1340,7 @@ GST_neighbours_send (const struct GNUNET_PeerIdentity *target, const void *msg,
1291 cont (cont_cls, GNUNET_SYSERR); 1340 cont (cont_cls, GNUNET_SYSERR);
1292 return; 1341 return;
1293 } 1342 }
1294 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "GST_neighbours_send %u %X %s\n", __LINE__ , n->session, GST_plugins_a2s(n->plugin_name, n->addr, n->addrlen)); 1343
1295 if ((n->session == NULL) && (n->addr == NULL) && (n->addrlen ==0)) 1344 if ((n->session == NULL) && (n->addr == NULL) && (n->addrlen ==0))
1296 { 1345 {
1297 GNUNET_STATISTICS_update (GST_stats, 1346 GNUNET_STATISTICS_update (GST_stats,
@@ -1308,7 +1357,7 @@ GST_neighbours_send (const struct GNUNET_PeerIdentity *target, const void *msg,
1308 cont (cont_cls, GNUNET_SYSERR); 1357 cont (cont_cls, GNUNET_SYSERR);
1309 return; 1358 return;
1310 } 1359 }
1311 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "GST_neighbours_send %u\n", __LINE__); 1360
1312 GNUNET_assert (msg_size >= sizeof (struct GNUNET_MessageHeader)); 1361 GNUNET_assert (msg_size >= sizeof (struct GNUNET_MessageHeader));
1313 GNUNET_STATISTICS_update (GST_stats, 1362 GNUNET_STATISTICS_update (GST_stats,
1314 gettext_noop 1363 gettext_noop
@@ -1324,8 +1373,6 @@ GST_neighbours_send (const struct GNUNET_PeerIdentity *target, const void *msg,
1324 mq->timeout = GNUNET_TIME_relative_to_absolute (timeout); 1373 mq->timeout = GNUNET_TIME_relative_to_absolute (timeout);
1325 GNUNET_CONTAINER_DLL_insert_tail (n->messages_head, n->messages_tail, mq); 1374 GNUNET_CONTAINER_DLL_insert_tail (n->messages_head, n->messages_tail, mq);
1326 1375
1327 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "GST_neighbours_send %u\n", __LINE__);
1328
1329 if ((GNUNET_SCHEDULER_NO_TASK == n->transmission_task) && 1376 if ((GNUNET_SCHEDULER_NO_TASK == n->transmission_task) &&
1330 (NULL == n->is_active)) 1377 (NULL == n->is_active))
1331 n->transmission_task = GNUNET_SCHEDULER_add_now (&transmission_task, n); 1378 n->transmission_task = GNUNET_SCHEDULER_add_now (&transmission_task, n);
@@ -1642,47 +1689,6 @@ GST_neighbours_handle_disconnect_message (const struct GNUNET_PeerIdentity *peer
1642 GST_neighbours_force_disconnect (peer); 1689 GST_neighbours_force_disconnect (peer);
1643} 1690}
1644 1691
1645static void neighbour_connected (struct NeighbourMapEntry *n,
1646 const struct GNUNET_ATS_Information *ats,
1647 uint32_t ats_count, int send_connect_ack)
1648{
1649 struct GNUNET_MessageHeader msg;
1650 size_t msg_len;
1651 int ret;
1652
1653 if (is_connected(n))
1654 return;
1655
1656 change_state (n, S_CONNECTED);
1657 n->keepalive_task = GNUNET_SCHEDULER_add_delayed (KEEPALIVE_FREQUENCY,
1658 &neighbour_keepalive_task,
1659 n);
1660
1661 if (send_connect_ack)
1662 {
1663 /* send CONNECT_ACK (SYN_ACK)*/
1664 msg_len = sizeof (msg);
1665 msg.size = htons (msg_len);
1666 msg.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_ACK);
1667
1668 ret = send_with_plugin (NULL, &n->id, (const char *) &msg, msg_len, 0,
1669 GNUNET_TIME_UNIT_FOREVER_REL, n->session, n->plugin_name, n->addr, n->addrlen, GNUNET_YES, NULL, NULL);
1670 if (ret == GNUNET_SYSERR)
1671 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1672 "Failed to send CONNECT_MESSAGE to `%4s' using plugin `%s' address '%s' session %X\n",
1673 GNUNET_i2s (&n->id), n->plugin_name,
1674 (n->addrlen == 0) ? "<inbound>" : GST_plugins_a2s (n->plugin_name,
1675 n->addr,
1676 n->addrlen),
1677 n->session);
1678 }
1679 neighbours_connected++;
1680 GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), 1,
1681 GNUNET_NO);
1682 connect_notify_cb (callback_cls, &n->id, ats, ats_count);
1683}
1684
1685
1686/** 1692/**
1687 * We received a 'SESSION_CONNECT_ACK' message from the other peer. 1693 * We received a 'SESSION_CONNECT_ACK' message from the other peer.
1688 * Consider switching to it. 1694 * Consider switching to it.
@@ -1707,8 +1713,12 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message,
1707 uint32_t ats_count) 1713 uint32_t ats_count)
1708{ 1714{
1709 const struct SessionConnectMessage *scm; 1715 const struct SessionConnectMessage *scm;
1716 struct GNUNET_MessageHeader msg;
1710 struct GNUNET_TIME_Absolute ts; 1717 struct GNUNET_TIME_Absolute ts;
1711 struct NeighbourMapEntry *n; 1718 struct NeighbourMapEntry *n;
1719 size_t msg_len;
1720 size_t ret;
1721
1712 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1722 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1713 "GST_neighbours_handle_connect_ack SYN/ACK\n"); 1723 "GST_neighbours_handle_connect_ack SYN/ACK\n");
1714 if (ntohs (message->size) != sizeof (struct SessionConnectMessage)) 1724 if (ntohs (message->size) != sizeof (struct SessionConnectMessage))
@@ -1743,7 +1753,33 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message,
1743 plugin_name, sender_address, sender_address_len, 1753 plugin_name, sender_address, sender_address_len,
1744 session, ats, ats_count); 1754 session, ats, ats_count);
1745 1755
1746 neighbour_connected (n, ats, ats_count, GNUNET_YES); 1756 change_state (n, S_CONNECTED);
1757 n->keepalive_task = GNUNET_SCHEDULER_add_delayed (KEEPALIVE_FREQUENCY,
1758 &neighbour_keepalive_task,
1759 n);
1760 /* send ACK (ACK)*/
1761 msg_len = sizeof (msg);
1762 msg.size = htons (msg_len);
1763 msg.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_ACK);
1764
1765 ret = send_with_plugin (&n->id, (const char *) &msg, msg_len, 0,
1766 GNUNET_TIME_UNIT_FOREVER_REL,
1767 n->session, n->plugin_name, n->addr, n->addrlen,
1768 GNUNET_YES, NULL, NULL);
1769
1770 if (ret == GNUNET_SYSERR)
1771 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1772 "Failed to send SESSION_ACK to `%4s' using plugin `%s' address '%s' session %X\n",
1773 GNUNET_i2s (&n->id), n->plugin_name,
1774 (n->addrlen == 0) ? "<inbound>" : GST_plugins_a2s (n->plugin_name,
1775 n->addr,
1776 n->addrlen),
1777 n->session);
1778
1779 neighbours_connected++;
1780 GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), 1,
1781 GNUNET_NO);
1782 connect_notify_cb (callback_cls, &n->id, ats, ats_count);
1747} 1783}
1748 1784
1749void 1785void
@@ -1773,7 +1809,8 @@ GST_neighbours_handle_ack (const struct GNUNET_MessageHeader *message,
1773 1809
1774 if (n->state != S_CONNECT_RECV) 1810 if (n->state != S_CONNECT_RECV)
1775 { 1811 {
1776 send_disconnect(n); 1812 send_disconnect (n);
1813 change_state (n, S_DISCONNECT);
1777 GNUNET_break (0); 1814 GNUNET_break (0);
1778 return; 1815 return;
1779 } 1816 }
@@ -1793,7 +1830,15 @@ GST_neighbours_handle_ack (const struct GNUNET_MessageHeader *message,
1793 plugin_name, sender_address, sender_address_len, 1830 plugin_name, sender_address, sender_address_len,
1794 session, ats, ats_count); 1831 session, ats, ats_count);
1795 1832
1796 neighbour_connected (n, ats, ats_count, GNUNET_NO); 1833 change_state (n, S_CONNECTED);
1834 n->keepalive_task = GNUNET_SCHEDULER_add_delayed (KEEPALIVE_FREQUENCY,
1835 &neighbour_keepalive_task,
1836 n);
1837
1838 neighbours_connected++;
1839 GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), 1,
1840 GNUNET_NO);
1841 connect_notify_cb (callback_cls, &n->id, ats, ats_count);
1797} 1842}
1798 1843
1799struct BlackListCheckContext 1844struct BlackListCheckContext
@@ -1855,7 +1900,7 @@ handle_connect_blacklist_cont (void *cls,
1855 1900
1856 GNUNET_free (bcc); 1901 GNUNET_free (bcc);
1857 1902
1858 if (n->state > S_NOT_CONNECTED) 1903 if (n->state != S_NOT_CONNECTED)
1859 return; 1904 return;
1860 change_state (n, S_CONNECT_RECV); 1905 change_state (n, S_CONNECT_RECV);
1861 1906
@@ -1887,6 +1932,7 @@ GST_neighbours_handle_connect (const struct GNUNET_MessageHeader *message,
1887 uint32_t ats_count) 1932 uint32_t ats_count)
1888{ 1933{
1889 const struct SessionConnectMessage *scm; 1934 const struct SessionConnectMessage *scm;
1935 struct NeighbourMapEntry * n;
1890 struct BlackListCheckContext * bcc = NULL; 1936 struct BlackListCheckContext * bcc = NULL;
1891 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1937 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1892 "GST_neighbours_handle_connect SYN\n"); 1938 "GST_neighbours_handle_connect SYN\n");
@@ -1900,7 +1946,18 @@ GST_neighbours_handle_connect (const struct GNUNET_MessageHeader *message,
1900 scm = (const struct SessionConnectMessage *) message; 1946 scm = (const struct SessionConnectMessage *) message;
1901 GNUNET_break_op (ntohl (scm->reserved) == 0); 1947 GNUNET_break_op (ntohl (scm->reserved) == 0);
1902 1948
1949 n = lookup_neighbour(peer);
1950 if (n != NULL)
1951 {
1952 /* connected peer switches addresses */
1953 if (is_connected(n))
1954 {
1955 GNUNET_ATS_address_update(GST_ats, peer, plugin_name, sender_address, sender_address_len, session, ats, ats_count);
1956 return;
1957 }
1958 }
1903 1959
1960 /* we are not connected to this peer */
1904 /* do blacklist check*/ 1961 /* do blacklist check*/
1905 bcc = GNUNET_malloc (sizeof (struct BlackListCheckContext) + 1962 bcc = GNUNET_malloc (sizeof (struct BlackListCheckContext) +
1906 sizeof (struct GNUNET_ATS_Information) * ats_count + 1963 sizeof (struct GNUNET_ATS_Information) * ats_count +