diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2011-11-09 16:39:28 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2011-11-09 16:39:28 +0000 |
commit | 255a8346839fa3931f7c4b305c998b69dd71f334 (patch) | |
tree | 3bc0806f944c7e4684f4c08c8a5dfb9bea78675d /src | |
parent | f67083411d4443bfac0abe9f4f42656936e92d9d (diff) | |
download | gnunet-255a8346839fa3931f7c4b305c998b69dd71f334.tar.gz gnunet-255a8346839fa3931f7c4b305c998b69dd71f334.zip |
implementing fast_reconnect state
Diffstat (limited to 'src')
-rw-r--r-- | src/transport/gnunet-service-transport_neighbours.c | 101 |
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 | |||
819 | disconnect_neighbour (struct NeighbourMapEntry *n) | 833 | disconnect_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 | ||