aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2011-11-09 16:39:28 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2011-11-09 16:39:28 +0000
commit255a8346839fa3931f7c4b305c998b69dd71f334 (patch)
tree3bc0806f944c7e4684f4c08c8a5dfb9bea78675d /src
parentf67083411d4443bfac0abe9f4f42656936e92d9d (diff)
downloadgnunet-255a8346839fa3931f7c4b305c998b69dd71f334.tar.gz
gnunet-255a8346839fa3931f7c4b305c998b69dd71f334.zip
implementing fast_reconnect state
Diffstat (limited to 'src')
-rw-r--r--src/transport/gnunet-service-transport_neighbours.c101
1 files changed, 64 insertions, 37 deletions
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c
index 40790dfe4..75a2dbaa4 100644
--- a/src/transport/gnunet-service-transport_neighbours.c
+++ b/src/transport/gnunet-service-transport_neighbours.c
@@ -208,6 +208,11 @@ enum State
208 S_CONNECTED, 208 S_CONNECTED,
209 209
210 /** 210 /**
211 * connection ended, fast reconnect
212 */
213 S_FAST_RECONNECT,
214
215 /**
211 * Disconnect in progress 216 * Disconnect in progress
212 */ 217 */
213 S_DISCONNECT 218 S_DISCONNECT
@@ -406,6 +411,9 @@ print_state (int state)
406 case S_NOT_CONNECTED: 411 case S_NOT_CONNECTED:
407 return "S_NOT_CONNECTED"; 412 return "S_NOT_CONNECTED";
408 break; 413 break;
414 case S_FAST_RECONNECT:
415 return "S_FAST_RECONNECT";
416 break;
409 default: 417 default:
410 GNUNET_break (0); 418 GNUNET_break (0);
411 break; 419 break;
@@ -476,11 +484,15 @@ change (struct NeighbourMapEntry *n, int state, int line)
476 allowed = GNUNET_YES; 484 allowed = GNUNET_YES;
477 break; 485 break;
478 case S_CONNECTED: 486 case S_CONNECTED:
479 if (state == S_DISCONNECT) 487 if ((state == S_DISCONNECT) || (state == S_FAST_RECONNECT))
480 allowed = GNUNET_YES; 488 allowed = GNUNET_YES;
481 break; 489 break;
482 case S_DISCONNECT: 490 case S_DISCONNECT:
483 break; 491 break;
492 case S_FAST_RECONNECT:
493 if ((state == S_CONNECT_SENT) || (state == S_DISCONNECT))
494 allowed = GNUNET_YES;
495 break;
484 default: 496 default:
485 GNUNET_break (0); 497 GNUNET_break (0);
486 break; 498 break;
@@ -497,21 +509,22 @@ change (struct NeighbourMapEntry *n, int state, int line)
497 GNUNET_free (new); 509 GNUNET_free (new);
498 return GNUNET_SYSERR; 510 return GNUNET_SYSERR;
499 } 511 }
500
501 n->state = state;
502#if DEBUG_TRANSPORT 512#if DEBUG_TRANSPORT
503 { 513 {
504 char *old = GNUNET_strdup (print_state (n->state)); 514 char *old = GNUNET_strdup (print_state (n->state));
505 char *new = GNUNET_strdup (print_state (state)); 515 char *new = GNUNET_strdup (print_state (state));
506 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 516 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
507 "State for neighbour `%s' %X changed from `%s' to `%s' in line %u\n", 517 "State for neighbour `%s' %X changed from `%s' to `%s' in line %u\n",
508 GNUNET_i2s (&n->id), n, old, new, line); 518 GNUNET_i2s (&n->id), n, old, new, line);
509 GNUNET_free (old); 519 GNUNET_free (old);
510 GNUNET_free (new); 520 GNUNET_free (new);
511 } 521 }
512#endif 522#endif
523 n->state = state;
524
513 switch (n->state) 525 switch (n->state)
514 { 526 {
527 case S_FAST_RECONNECT:
515 case S_CONNECT_RECV: 528 case S_CONNECT_RECV:
516 case S_CONNECT_SENT: 529 case S_CONNECT_SENT:
517 if (n->state_reset != GNUNET_SCHEDULER_NO_TASK) 530 if (n->state_reset != GNUNET_SCHEDULER_NO_TASK)
@@ -540,6 +553,7 @@ change (struct NeighbourMapEntry *n, int state, int line)
540 n->state_reset = GNUNET_SCHEDULER_NO_TASK; 553 n->state_reset = GNUNET_SCHEDULER_NO_TASK;
541 } 554 }
542 break; 555 break;
556
543 default: 557 default:
544 GNUNET_assert (0); 558 GNUNET_assert (0);
545 } 559 }
@@ -819,12 +833,15 @@ static void
819disconnect_neighbour (struct NeighbourMapEntry *n) 833disconnect_neighbour (struct NeighbourMapEntry *n)
820{ 834{
821 struct MessageQueue *mq; 835 struct MessageQueue *mq;
822 int is_connected; 836 int previous_state;
823 837
824 is_connected = (n->state == S_CONNECTED); 838 previous_state = n->state;
839
840 if (is_disconnecting (n))
841 return;
825 842
826 /* send DISCONNECT MESSAGE */ 843 /* send DISCONNECT MESSAGE */
827 if (is_connected || is_connecting (n)) 844 if ((previous_state == S_CONNECTED)|| is_connecting (n))
828 { 845 {
829 if (GNUNET_OK == 846 if (GNUNET_OK ==
830 send_disconnect (&n->id, n->address, 847 send_disconnect (&n->id, n->address,
@@ -837,20 +854,18 @@ disconnect_neighbour (struct NeighbourMapEntry *n)
837 GNUNET_i2s (&n->id)); 854 GNUNET_i2s (&n->id));
838 } 855 }
839 856
840 if (is_connected)
841 {
842 GNUNET_ATS_address_in_use (GST_ats, n->address, n->session, GNUNET_NO);
843 }
844
845
846 if (is_disconnecting (n))
847 return;
848 change_state (n, S_DISCONNECT); 857 change_state (n, S_DISCONNECT);
849 GST_validation_set_address_use (&n->id, 858 GST_validation_set_address_use (&n->id,
850 n->address, 859 n->address,
851 n->session, 860 n->session,
852 GNUNET_NO); 861 GNUNET_NO);
853 862
863 if (n->state == S_CONNECTED)
864 {
865 GNUNET_assert (NULL != n->address);
866 GNUNET_ATS_address_in_use (GST_ats, n->address, n->session, GNUNET_NO);
867 }
868
854 if (n->address != NULL) 869 if (n->address != NULL)
855 { 870 {
856 struct GNUNET_TRANSPORT_PluginFunctions *papi; 871 struct GNUNET_TRANSPORT_PluginFunctions *papi;
@@ -858,7 +873,6 @@ disconnect_neighbour (struct NeighbourMapEntry *n)
858 if (papi != NULL) 873 if (papi != NULL)
859 papi->disconnect (papi->cls, &n->id); 874 papi->disconnect (papi->cls, &n->id);
860 } 875 }
861
862 while (NULL != (mq = n->messages_head)) 876 while (NULL != (mq = n->messages_head))
863 { 877 {
864 GNUNET_CONTAINER_DLL_remove (n->messages_head, n->messages_tail, mq); 878 GNUNET_CONTAINER_DLL_remove (n->messages_head, n->messages_tail, mq);
@@ -871,17 +885,28 @@ disconnect_neighbour (struct NeighbourMapEntry *n)
871 n->is_active->n = NULL; 885 n->is_active->n = NULL;
872 n->is_active = NULL; 886 n->is_active = NULL;
873 } 887 }
874 if (is_connected) 888
875 { 889 switch (previous_state) {
876 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != n->keepalive_task); 890 case S_CONNECTED:
877 GNUNET_SCHEDULER_cancel (n->keepalive_task); 891 GNUNET_assert (neighbours_connected > 0);
878 n->keepalive_task = GNUNET_SCHEDULER_NO_TASK; 892 neighbours_connected--;
879 GNUNET_assert (neighbours_connected > 0); 893 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != n->keepalive_task);
880 neighbours_connected--; 894 GNUNET_SCHEDULER_cancel (n->keepalive_task);
881 GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), -1, 895 n->keepalive_task = GNUNET_SCHEDULER_NO_TASK;
882 GNUNET_NO); 896 GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), -1,
883 disconnect_notify_cb (callback_cls, &n->id); 897 GNUNET_NO);
898 disconnect_notify_cb (callback_cls, &n->id);
899 break;
900 case S_FAST_RECONNECT:
901 GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), -1,
902 GNUNET_NO);
903 disconnect_notify_cb (callback_cls, &n->id);
904 default:
905 break;
884 } 906 }
907
908 GNUNET_ATS_suggest_address_cancel (GST_ats, &n->id);
909
885 GNUNET_assert (GNUNET_YES == 910 GNUNET_assert (GNUNET_YES ==
886 GNUNET_CONTAINER_multihashmap_remove (neighbours, 911 GNUNET_CONTAINER_multihashmap_remove (neighbours,
887 &n->id.hashPubKey, n)); 912 &n->id.hashPubKey, n));
@@ -1269,6 +1294,7 @@ GST_neighbours_switch_to_address_3way (const struct GNUNET_PeerIdentity *peer,
1269 { 1294 {
1270 case S_NOT_CONNECTED: 1295 case S_NOT_CONNECTED:
1271 case S_CONNECT_SENT: 1296 case S_CONNECT_SENT:
1297 case S_FAST_RECONNECT:
1272 msg_len = sizeof (struct SessionConnectMessage); 1298 msg_len = sizeof (struct SessionConnectMessage);
1273 connect_msg.header.size = htons (msg_len); 1299 connect_msg.header.size = htons (msg_len);
1274 connect_msg.header.type = 1300 connect_msg.header.type =
@@ -1503,7 +1529,16 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer,
1503 /* not connected anymore anyway, shouldn't matter */ 1529 /* not connected anymore anyway, shouldn't matter */
1504 if ((S_CONNECTED != n->state) && (!is_connecting (n))) 1530 if ((S_CONNECTED != n->state) && (!is_connecting (n)))
1505 return; 1531 return;
1506 // FIXME: n->state = S_FAST_RECONNECT; 1532 change_state (n, S_FAST_RECONNECT);
1533
1534 GNUNET_assert (neighbours_connected > 0);
1535 neighbours_connected--;
1536
1537 if (n->keepalive_task != GNUNET_SCHEDULER_NO_TASK)
1538 {
1539 GNUNET_SCHEDULER_cancel (n->keepalive_task);
1540 n->keepalive_task = GNUNET_SCHEDULER_NO_TASK;
1541 }
1507 1542
1508 /* We are connected, so ask ATS to switch addresses */ 1543 /* We are connected, so ask ATS to switch addresses */
1509 GNUNET_SCHEDULER_cancel (n->timeout_task); 1544 GNUNET_SCHEDULER_cancel (n->timeout_task);
@@ -1854,14 +1889,6 @@ GST_neighbours_force_disconnect (const struct GNUNET_PeerIdentity *target)
1854 n = lookup_neighbour (target); 1889 n = lookup_neighbour (target);
1855 if (NULL == n) 1890 if (NULL == n)
1856 return; /* not active */ 1891 return; /* not active */
1857 if (is_connected (n))
1858 {
1859 send_disconnect (&n->id, n->address, n->session);
1860
1861 n = lookup_neighbour (target);
1862 if (NULL == n)
1863 return; /* gone already */
1864 }
1865 disconnect_neighbour (n); 1892 disconnect_neighbour (n);
1866} 1893}
1867 1894