diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2011-10-27 13:01:11 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2011-10-27 13:01:11 +0000 |
commit | 64d5a91798af32dd3a5183ee5e9ddafcbc376ead (patch) | |
tree | d056f24147f6a92453556a1789df2178d0f9b6fc /src/transport | |
parent | 19780f69c439907bbe4d35265ac1b7ad092c50cd (diff) | |
download | gnunet-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.c | 325 |
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 | ||
368 | static int | 368 | static const char * |
369 | change (struct NeighbourMapEntry * n, int state, int line) | 369 | print_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 | |||
397 | static int | ||
398 | change (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 | ||
483 | static ssize_t | 468 | static ssize_t |
484 | send_with_plugin (void *cls, | 469 | send_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) | |||
654 | static void | 636 | static void |
655 | transmission_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 637 | transmission_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 | ||
663 | static void | ||
664 | send_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 | ||
683 | static int | 676 | static int |
684 | send_disconnect (struct NeighbourMapEntry *n) | 677 | send_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 | */ | ||
952 | static void | ||
953 | send_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); | ||
970 | return; | ||
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 | ||
1645 | static 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 | ||
1749 | void | 1785 | void |
@@ -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 | ||
1799 | struct BlackListCheckContext | 1844 | struct 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 + |