aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-02-16 22:19:04 +0000
committerChristian Grothoff <christian@grothoff.org>2010-02-16 22:19:04 +0000
commitf620d1eee9cb74eed3d87676a61893a906c5ae79 (patch)
tree65bbcec5e6ca39418b371b951496ed84354b1265 /src
parent37971663cf6b082c4d754c711310ba3ac1685b14 (diff)
downloadgnunet-f620d1eee9cb74eed3d87676a61893a906c5ae79.tar.gz
gnunet-f620d1eee9cb74eed3d87676a61893a906c5ae79.zip
fixes
Diffstat (limited to 'src')
-rw-r--r--src/core/gnunet-service-core.c432
-rw-r--r--src/core/test_core_api_peer1.conf3
-rw-r--r--src/core/test_core_api_peer2.conf3
-rw-r--r--src/transport/gnunet-service-transport.c329
-rw-r--r--src/transport/transport.h7
-rw-r--r--src/transport/transport_api.c3
6 files changed, 435 insertions, 342 deletions
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c
index 08c1c5455..ff71eddd3 100644
--- a/src/core/gnunet-service-core.c
+++ b/src/core/gnunet-service-core.c
@@ -427,6 +427,11 @@ struct Neighbour
427 GNUNET_SCHEDULER_TaskIdentifier quota_update_task; 427 GNUNET_SCHEDULER_TaskIdentifier quota_update_task;
428 428
429 /** 429 /**
430 * ID of task used for cleaning up dead neighbour entries.
431 */
432 GNUNET_SCHEDULER_TaskIdentifier dead_clean_task;
433
434 /**
430 * At what time did we generate our encryption key? 435 * At what time did we generate our encryption key?
431 */ 436 */
432 struct GNUNET_TIME_Absolute encrypt_key_created; 437 struct GNUNET_TIME_Absolute encrypt_key_created;
@@ -552,6 +557,10 @@ struct Neighbour
552 */ 557 */
553 enum PeerStateMachine status; 558 enum PeerStateMachine status;
554 559
560 /**
561 * Are we currently connected to this neighbour?
562 */
563 int is_connected;
555}; 564};
556 565
557 566
@@ -861,14 +870,17 @@ handle_client_init (void *cls,
861 n = neighbours; 870 n = neighbours;
862 while (n != NULL) 871 while (n != NULL)
863 { 872 {
873 if (n->status == PEER_STATE_KEY_CONFIRMED)
874 {
864#if DEBUG_CORE_CLIENT 875#if DEBUG_CORE_CLIENT
865 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 876 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
866 "Sending `%s' message to client.\n", "NOTIFY_CONNECT"); 877 "Sending `%s' message to client.\n", "NOTIFY_CONNECT");
867#endif 878#endif
868 cnm.distance = htonl (n->last_distance); 879 cnm.distance = htonl (n->last_distance);
869 cnm.latency = GNUNET_TIME_relative_hton (n->last_latency); 880 cnm.latency = GNUNET_TIME_relative_hton (n->last_latency);
870 cnm.peer = n->peer; 881 cnm.peer = n->peer;
871 send_to_client (c, &cnm.header, GNUNET_NO); 882 send_to_client (c, &cnm.header, GNUNET_NO);
883 }
872 n = n->next; 884 n = n->next;
873 } 885 }
874 GNUNET_SERVER_receive_done (client, GNUNET_OK); 886 GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -935,7 +947,7 @@ handle_client_request_info (void *cls,
935 rcm = (const struct RequestInfoMessage *) message; 947 rcm = (const struct RequestInfoMessage *) message;
936 n = find_neighbour (&rcm->peer); 948 n = find_neighbour (&rcm->peer);
937 memset (&cim, 0, sizeof (cim)); 949 memset (&cim, 0, sizeof (cim));
938 if ((n != NULL) && (n->status == PEER_STATE_KEY_CONFIRMED)) 950 if (n != NULL)
939 { 951 {
940 update_window (GNUNET_YES, 952 update_window (GNUNET_YES,
941 &n->available_send_window, 953 &n->available_send_window,
@@ -987,6 +999,129 @@ handle_client_request_info (void *cls,
987 999
988 1000
989/** 1001/**
1002 * Free the given entry for the neighbour (it has
1003 * already been removed from the list at this point).
1004 *
1005 * @param n neighbour to free
1006 */
1007static void
1008free_neighbour (struct Neighbour *n)
1009{
1010 struct MessageEntry *m;
1011
1012 if (n->pitr != NULL)
1013 {
1014 GNUNET_PEERINFO_iterate_cancel (n->pitr);
1015 n->pitr = NULL;
1016 }
1017 if (n->skm != NULL)
1018 {
1019 GNUNET_free (n->skm);
1020 n->skm = NULL;
1021 }
1022 while (NULL != (m = n->messages))
1023 {
1024 n->messages = m->next;
1025 GNUNET_free (m);
1026 }
1027 while (NULL != (m = n->encrypted_head))
1028 {
1029 n->encrypted_head = m->next;
1030 GNUNET_free (m);
1031 }
1032 if (NULL != n->th)
1033 GNUNET_TRANSPORT_notify_transmit_ready_cancel (n->th);
1034 if (n->retry_plaintext_task != GNUNET_SCHEDULER_NO_TASK)
1035 GNUNET_SCHEDULER_cancel (sched, n->retry_plaintext_task);
1036 if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK)
1037 GNUNET_SCHEDULER_cancel (sched, n->retry_set_key_task);
1038 if (n->quota_update_task != GNUNET_SCHEDULER_NO_TASK)
1039 GNUNET_SCHEDULER_cancel (sched, n->quota_update_task);
1040 if (n->dead_clean_task != GNUNET_SCHEDULER_NO_TASK)
1041 GNUNET_SCHEDULER_cancel (sched, n->dead_clean_task);
1042 GNUNET_free_non_null (n->public_key);
1043 GNUNET_free_non_null (n->pending_ping);
1044 GNUNET_free_non_null (n->pending_pong);
1045 GNUNET_free (n);
1046}
1047
1048
1049/**
1050 * Consider freeing the given neighbour since we may not need
1051 * to keep it around anymore.
1052 *
1053 * @param n neighbour to consider discarding
1054 */
1055static void
1056consider_free_neighbour (struct Neighbour *n);
1057
1058
1059/**
1060 * Task triggered when a neighbour entry might have gotten stale.
1061 *
1062 * @param cls the 'struct Neighbour'
1063 * @param tc scheduler context (not used)
1064 */
1065static void
1066consider_free_task (void *cls,
1067 const struct GNUNET_SCHEDULER_TaskContext *tc)
1068{
1069 struct Neighbour *n = cls;
1070 n->dead_clean_task = GNUNET_SCHEDULER_NO_TASK;
1071 consider_free_neighbour (n);
1072}
1073
1074
1075/**
1076 * Consider freeing the given neighbour since we may not need
1077 * to keep it around anymore.
1078 *
1079 * @param n neighbour to consider discarding
1080 */
1081static void
1082consider_free_neighbour (struct Neighbour *n)
1083{
1084 struct Neighbour *pos;
1085 struct Neighbour *prev;
1086 struct GNUNET_TIME_Relative left;
1087
1088 if ( (n->th != NULL) ||
1089 (n->pitr != NULL) ||
1090 (n->status == PEER_STATE_KEY_CONFIRMED) ||
1091 (GNUNET_YES == n->is_connected) )
1092 return; /* no chance */
1093
1094 left = GNUNET_TIME_absolute_get_remaining (GNUNET_TIME_absolute_add (n->last_activity,
1095 MAX_PONG_DELAY));
1096 if (left.value > 0)
1097 {
1098 if (n->dead_clean_task != GNUNET_SCHEDULER_NO_TASK)
1099 GNUNET_SCHEDULER_cancel (sched, n->dead_clean_task);
1100 n->dead_clean_task = GNUNET_SCHEDULER_add_delayed (sched,
1101 left,
1102 &consider_free_task,
1103 n);
1104 return;
1105 }
1106 /* actually free the neighbour... */
1107 prev = NULL;
1108 pos = neighbours;
1109 while (pos != n)
1110 {
1111 prev = pos;
1112 pos = pos->next;
1113 }
1114 if (prev == NULL)
1115 neighbours = n->next;
1116 else
1117 prev->next = n->next;
1118 GNUNET_assert (neighbour_count > 0);
1119 neighbour_count--;
1120 free_neighbour (n);
1121}
1122
1123
1124/**
990 * Check if we have encrypted messages for the specified neighbour 1125 * Check if we have encrypted messages for the specified neighbour
991 * pending, and if so, check with the transport about sending them 1126 * pending, and if so, check with the transport about sending them
992 * out. 1127 * out.
@@ -1038,11 +1173,12 @@ notify_encrypted_transmit_ready (void *cls, size_t size, void *buf)
1038 else 1173 else
1039 { 1174 {
1040 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1175 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1041 "Transmission for message of type %u and size %u failed\n", 1176 "Transmission of message of type %u and size %u failed\n",
1042 ntohs (((struct GNUNET_MessageHeader *) &m[1])->type), 1177 ntohs (((struct GNUNET_MessageHeader *) &m[1])->type),
1043 m->size); 1178 m->size);
1044 } 1179 }
1045 GNUNET_free (m); 1180 GNUNET_free (m);
1181 consider_free_neighbour (n);
1046 return ret; 1182 return ret;
1047} 1183}
1048 1184
@@ -1702,55 +1838,71 @@ process_plaintext_neighbour_queue (struct Neighbour *n)
1702 1838
1703 1839
1704/** 1840/**
1705 * Handle CORE_SEND request. 1841 * Function that recalculates the bandwidth quota for the
1706 * 1842 * given neighbour and transmits it to the transport service.
1707 * @param cls unused 1843 *
1708 * @param client the client issuing the request 1844 * @param cls neighbour for the quota update
1709 * @param message the "struct SendMessage" 1845 * @param tc context
1710 */ 1846 */
1711static void 1847static void
1712handle_client_send (void *cls, 1848neighbour_quota_update (void *cls,
1713 struct GNUNET_SERVER_Client *client, 1849 const struct GNUNET_SCHEDULER_TaskContext *tc);
1714 const struct GNUNET_MessageHeader *message); 1850
1851
1852/**
1853 * Schedule the task that will recalculate the bandwidth
1854 * quota for this peer (and possibly force a disconnect of
1855 * idle peers by calculating a bandwidth of zero).
1856 */
1857static void
1858schedule_quota_update (struct Neighbour *n)
1859{
1860 GNUNET_assert (n->quota_update_task ==
1861 GNUNET_SCHEDULER_NO_TASK);
1862 n->quota_update_task
1863 = GNUNET_SCHEDULER_add_delayed (sched,
1864 QUOTA_UPDATE_FREQUENCY,
1865 &neighbour_quota_update,
1866 n);
1867}
1715 1868
1716 1869
1717/** 1870/**
1718 * Function called to notify us that we either succeeded 1871 * Initialize a new 'struct Neighbour'.
1719 * or failed to connect (at the transport level) to another
1720 * peer. We should either free the message we were asked
1721 * to transmit or re-try adding it to the queue.
1722 * 1872 *
1723 * @param cls closure 1873 * @param pid ID of the new neighbour
1724 * @param size number of bytes available in buf 1874 * @return handle for the new neighbour
1725 * @param buf where the callee should write the message
1726 * @return number of bytes written to buf
1727 */ 1875 */
1728static size_t 1876static struct Neighbour *
1729send_connect_continuation (void *cls, size_t size, void *buf) 1877create_neighbour (const struct GNUNET_PeerIdentity *pid)
1730{ 1878{
1731 struct SendMessage *sm = cls; 1879 struct Neighbour *n;
1880 struct GNUNET_TIME_Absolute now;
1732 1881
1733 if (buf == NULL) 1882 n = GNUNET_malloc (sizeof (struct Neighbour));
1734 { 1883 n->next = neighbours;
1735#if DEBUG_CORE 1884 neighbours = n;
1736 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1885 neighbour_count++;
1737 "Asked to send message to disconnected peer `%4s' and connection failed. Discarding message.\n", 1886 n->peer = *pid;
1738 GNUNET_i2s (&sm->peer)); 1887 GNUNET_CRYPTO_aes_create_session_key (&n->encrypt_key);
1739#endif 1888 now = GNUNET_TIME_absolute_get ();
1740 GNUNET_free (sm); 1889 n->encrypt_key_created = now;
1741 return 0; 1890 n->last_activity = now;
1742 } 1891 n->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY;
1743#if DEBUG_CORE 1892 n->bpm_in = GNUNET_CONSTANTS_DEFAULT_BPM_IN_OUT;
1744 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1893 n->bpm_out = GNUNET_CONSTANTS_DEFAULT_BPM_IN_OUT;
1745 "Connection to peer `%4s' succeeded, retrying original transmission request\n", 1894 n->bpm_out_internal_limit = (uint32_t) - 1;
1746 GNUNET_i2s (&sm->peer)); 1895 n->bpm_out_external_limit = GNUNET_CONSTANTS_DEFAULT_BPM_IN_OUT;
1747#endif 1896 n->ping_challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
1748 handle_client_send (NULL, NULL, &sm->header); 1897 (uint32_t) - 1);
1749 GNUNET_free (sm); 1898 schedule_quota_update (n);
1750 return 0; 1899 return n;
1751} 1900}
1752 1901
1753 1902
1903
1904
1905
1754/** 1906/**
1755 * Handle CORE_SEND request. 1907 * Handle CORE_SEND request.
1756 * 1908 *
@@ -1764,7 +1916,6 @@ handle_client_send (void *cls,
1764 const struct GNUNET_MessageHeader *message) 1916 const struct GNUNET_MessageHeader *message)
1765{ 1917{
1766 const struct SendMessage *sm; 1918 const struct SendMessage *sm;
1767 struct SendMessage *smc;
1768 const struct GNUNET_MessageHeader *mh; 1919 const struct GNUNET_MessageHeader *mh;
1769 struct Neighbour *n; 1920 struct Neighbour *n;
1770 struct MessageEntry *prev; 1921 struct MessageEntry *prev;
@@ -1797,41 +1948,7 @@ handle_client_send (void *cls,
1797 } 1948 }
1798 n = find_neighbour (&sm->peer); 1949 n = find_neighbour (&sm->peer);
1799 if (n == NULL) 1950 if (n == NULL)
1800 { 1951 n = create_neighbour (&sm->peer);
1801#if DEBUG_CORE
1802 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1803 "Core received `%s' request for `%4s', will try to establish connection within %llu ms\n",
1804 "SEND",
1805 GNUNET_i2s (&sm->peer),
1806 GNUNET_TIME_absolute_get_remaining
1807 (GNUNET_TIME_absolute_ntoh(sm->deadline)).value);
1808#endif
1809 msize += sizeof (struct SendMessage);
1810 /* ask transport to connect to the peer */
1811 smc = GNUNET_malloc (msize);
1812 memcpy (smc, sm, msize);
1813 if (NULL ==
1814 GNUNET_TRANSPORT_notify_transmit_ready (transport,
1815 &sm->peer,
1816 0, 0,
1817 GNUNET_TIME_absolute_get_remaining
1818 (GNUNET_TIME_absolute_ntoh
1819 (sm->deadline)),
1820 &send_connect_continuation,
1821 smc))
1822 {
1823 /* transport has already a request pending for this peer! */
1824#if DEBUG_CORE
1825 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1826 "Dropped second message destined for `%4s' since connection is still down.\n",
1827 GNUNET_i2s(&sm->peer));
1828#endif
1829 GNUNET_free (smc);
1830 }
1831 if (client != NULL)
1832 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1833 return;
1834 }
1835#if DEBUG_CORE 1952#if DEBUG_CORE
1836 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1953 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1837 "Core received `%s' request, queueing %u bytes of plaintext data for transmission to `%4s'.\n", 1954 "Core received `%s' request, queueing %u bytes of plaintext data for transmission to `%4s'.\n",
@@ -1934,7 +2051,10 @@ handle_client_request_connect (void *cls,
1934 2051
1935 GNUNET_SERVER_receive_done (client, GNUNET_OK); 2052 GNUNET_SERVER_receive_done (client, GNUNET_OK);
1936 n = find_neighbour (&cm->peer); 2053 n = find_neighbour (&cm->peer);
1937 if (n != NULL) 2054 if (n == NULL)
2055 n = create_neighbour (&cm->peer);
2056 if ( (n->is_connected) ||
2057 (n->th != NULL) )
1938 return; /* already connected, or at least trying */ 2058 return; /* already connected, or at least trying */
1939#if DEBUG_CORE 2059#if DEBUG_CORE
1940 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2060 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1943,13 +2063,13 @@ handle_client_request_connect (void *cls,
1943 GNUNET_i2s (&cm->peer)); 2063 GNUNET_i2s (&cm->peer));
1944#endif 2064#endif
1945 /* ask transport to connect to the peer */ 2065 /* ask transport to connect to the peer */
1946 /* FIXME: timeout zero OK? need for cancellation? */ 2066 /* FIXME: timeout zero OK? */
1947 GNUNET_TRANSPORT_notify_transmit_ready (transport, 2067 n->th = GNUNET_TRANSPORT_notify_transmit_ready (transport,
1948 &cm->peer, 2068 &cm->peer,
1949 0, 0, 2069 0, 0,
1950 GNUNET_TIME_UNIT_ZERO, 2070 GNUNET_TIME_UNIT_ZERO,
1951 NULL, 2071 NULL,
1952 NULL); 2072 NULL);
1953} 2073}
1954 2074
1955 2075
@@ -1977,7 +2097,7 @@ static struct GNUNET_SERVER_MessageHandler handlers[] = {
1977 * the neighbour's struct and retry send_key. Or, if we did not get a 2097 * the neighbour's struct and retry send_key. Or, if we did not get a
1978 * HELLO, just do nothing. 2098 * HELLO, just do nothing.
1979 * 2099 *
1980 * @param cls NULL 2100 * @param cls the 'struct Neighbour' to retry sending the key for
1981 * @param peer the peer for which this is the HELLO 2101 * @param peer the peer for which this is the HELLO
1982 * @param hello HELLO message of that peer 2102 * @param hello HELLO message of that peer
1983 * @param trust amount of trust we currently have in that peer 2103 * @param trust amount of trust we currently have in that peer
@@ -2086,7 +2206,6 @@ send_key (struct Neighbour *n)
2086 GNUNET_i2s (&n->peer)); 2206 GNUNET_i2s (&n->peer));
2087#endif 2207#endif
2088 GNUNET_assert (n->pitr == NULL); 2208 GNUNET_assert (n->pitr == NULL);
2089 //sleep(10);
2090 n->pitr = GNUNET_PEERINFO_iterate (cfg, 2209 n->pitr = GNUNET_PEERINFO_iterate (cfg,
2091 sched, 2210 sched,
2092 &n->peer, 2211 &n->peer,
@@ -2861,6 +2980,7 @@ handle_transport_receive (void *cls,
2861 GNUNET_break (0); 2980 GNUNET_break (0);
2862 return; 2981 return;
2863 } 2982 }
2983 GNUNET_break (n->is_connected);
2864 n->last_latency = latency; 2984 n->last_latency = latency;
2865 n->last_distance = distance; 2985 n->last_distance = distance;
2866 up = (n->status == PEER_STATE_KEY_CONFIRMED); 2986 up = (n->status == PEER_STATE_KEY_CONFIRMED);
@@ -2963,36 +3083,6 @@ handle_transport_receive (void *cls,
2963 */ 3083 */
2964static void 3084static void
2965neighbour_quota_update (void *cls, 3085neighbour_quota_update (void *cls,
2966 const struct GNUNET_SCHEDULER_TaskContext *tc);
2967
2968
2969/**
2970 * Schedule the task that will recalculate the bandwidth
2971 * quota for this peer (and possibly force a disconnect of
2972 * idle peers by calculating a bandwidth of zero).
2973 */
2974static void
2975schedule_quota_update (struct Neighbour *n)
2976{
2977 GNUNET_assert (n->quota_update_task ==
2978 GNUNET_SCHEDULER_NO_TASK);
2979 n->quota_update_task
2980 = GNUNET_SCHEDULER_add_delayed (sched,
2981 QUOTA_UPDATE_FREQUENCY,
2982 &neighbour_quota_update,
2983 n);
2984}
2985
2986
2987/**
2988 * Function that recalculates the bandwidth quota for the
2989 * given neighbour and transmits it to the transport service.
2990 *
2991 * @param cls neighbour for the quota update
2992 * @param tc context
2993 */
2994static void
2995neighbour_quota_update (void *cls,
2996 const struct GNUNET_SCHEDULER_TaskContext *tc) 3086 const struct GNUNET_SCHEDULER_TaskContext *tc)
2997{ 3087{
2998 struct Neighbour *n = cls; 3088 struct Neighbour *n = cls;
@@ -3060,36 +3150,28 @@ handle_transport_notify_connect (void *cls,
3060 n = find_neighbour (peer); 3150 n = find_neighbour (peer);
3061 if (n != NULL) 3151 if (n != NULL)
3062 { 3152 {
3063 /* duplicate connect notification!? */ 3153 if (n->is_connected)
3064 GNUNET_break (0); 3154 {
3065 return; 3155 /* duplicate connect notification!? */
3156 GNUNET_break (0);
3157 return;
3158 }
3159 }
3160 else
3161 {
3162 n = create_neighbour (peer);
3066 } 3163 }
3067 now = GNUNET_TIME_absolute_get (); 3164 now = GNUNET_TIME_absolute_get ();
3068 n = GNUNET_malloc (sizeof (struct Neighbour)); 3165 n->is_connected = GNUNET_YES;
3069 n->next = neighbours;
3070 neighbours = n;
3071 neighbour_count++;
3072 n->peer = *peer;
3073 n->last_latency = latency; 3166 n->last_latency = latency;
3074 n->last_distance = distance; 3167 n->last_distance = distance;
3075 GNUNET_CRYPTO_aes_create_session_key (&n->encrypt_key);
3076 n->encrypt_key_created = now;
3077 n->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY;
3078 n->last_activity = now;
3079 n->last_asw_update = now; 3168 n->last_asw_update = now;
3080 n->last_arw_update = now; 3169 n->last_arw_update = now;
3081 n->bpm_in = GNUNET_CONSTANTS_DEFAULT_BPM_IN_OUT;
3082 n->bpm_out = GNUNET_CONSTANTS_DEFAULT_BPM_IN_OUT;
3083 n->bpm_out_internal_limit = (uint32_t) - 1;
3084 n->bpm_out_external_limit = GNUNET_CONSTANTS_DEFAULT_BPM_IN_OUT;
3085 n->ping_challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
3086 (uint32_t) - 1);
3087#if DEBUG_CORE 3170#if DEBUG_CORE
3088 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3171 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3089 "Received connection from `%4s'.\n", 3172 "Received connection from `%4s'.\n",
3090 GNUNET_i2s (&n->peer)); 3173 GNUNET_i2s (&n->peer));
3091#endif 3174#endif
3092 schedule_quota_update (n);
3093 cnm.header.size = htons (sizeof (struct ConnectNotifyMessage)); 3175 cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
3094 cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_PRE_CONNECT); 3176 cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_PRE_CONNECT);
3095 cnm.distance = htonl (n->last_distance); 3177 cnm.distance = htonl (n->last_distance);
@@ -3101,52 +3183,6 @@ handle_transport_notify_connect (void *cls,
3101 3183
3102 3184
3103/** 3185/**
3104 * Free the given entry for the neighbour (it has
3105 * already been removed from the list at this point).
3106 *
3107 * @param n neighbour to free
3108 */
3109static void
3110free_neighbour (struct Neighbour *n)
3111{
3112 struct MessageEntry *m;
3113
3114 if (n->pitr != NULL)
3115 {
3116 GNUNET_PEERINFO_iterate_cancel (n->pitr);
3117 n->pitr = NULL;
3118 }
3119 if (n->skm != NULL)
3120 {
3121 GNUNET_free (n->skm);
3122 n->skm = NULL;
3123 }
3124 while (NULL != (m = n->messages))
3125 {
3126 n->messages = m->next;
3127 GNUNET_free (m);
3128 }
3129 while (NULL != (m = n->encrypted_head))
3130 {
3131 n->encrypted_head = m->next;
3132 GNUNET_free (m);
3133 }
3134 if (NULL != n->th)
3135 GNUNET_TRANSPORT_notify_transmit_ready_cancel (n->th);
3136 if (n->retry_plaintext_task != GNUNET_SCHEDULER_NO_TASK)
3137 GNUNET_SCHEDULER_cancel (sched, n->retry_plaintext_task);
3138 if (n->retry_set_key_task != GNUNET_SCHEDULER_NO_TASK)
3139 GNUNET_SCHEDULER_cancel (sched, n->retry_set_key_task);
3140 if (n->quota_update_task != GNUNET_SCHEDULER_NO_TASK)
3141 GNUNET_SCHEDULER_cancel (sched, n->quota_update_task);
3142 GNUNET_free_non_null (n->public_key);
3143 GNUNET_free_non_null (n->pending_ping);
3144 GNUNET_free_non_null (n->pending_pong);
3145 GNUNET_free (n);
3146}
3147
3148
3149/**
3150 * Function called by transport telling us that a peer 3186 * Function called by transport telling us that a peer
3151 * disconnected. 3187 * disconnected.
3152 * 3188 *
@@ -3159,36 +3195,18 @@ handle_transport_notify_disconnect (void *cls,
3159{ 3195{
3160 struct DisconnectNotifyMessage cnm; 3196 struct DisconnectNotifyMessage cnm;
3161 struct Neighbour *n; 3197 struct Neighbour *n;
3162 struct Neighbour *p;
3163 3198
3164#if DEBUG_CORE 3199#if DEBUG_CORE
3165 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3200 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3166 "Peer `%4s' disconnected from us.\n", GNUNET_i2s (peer)); 3201 "Peer `%4s' disconnected from us.\n", GNUNET_i2s (peer));
3167#endif 3202#endif
3168 p = NULL; 3203 n = find_neighbour (peer);
3169 n = neighbours; 3204 GNUNET_break (n->is_connected);
3170 while ((n != NULL) &&
3171 (0 != memcmp (&n->peer, peer, sizeof (struct GNUNET_PeerIdentity))))
3172 {
3173 p = n;
3174 n = n->next;
3175 }
3176 if (n == NULL)
3177 {
3178 GNUNET_break (0);
3179 return;
3180 }
3181 if (p == NULL)
3182 neighbours = n->next;
3183 else
3184 p->next = n->next;
3185 GNUNET_assert (neighbour_count > 0);
3186 neighbour_count--;
3187 cnm.header.size = htons (sizeof (struct DisconnectNotifyMessage)); 3205 cnm.header.size = htons (sizeof (struct DisconnectNotifyMessage));
3188 cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT); 3206 cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT);
3189 cnm.peer = *peer; 3207 cnm.peer = *peer;
3190 send_to_all_clients (&cnm.header, GNUNET_YES, GNUNET_CORE_OPTION_SEND_DISCONNECT); 3208 send_to_all_clients (&cnm.header, GNUNET_YES, GNUNET_CORE_OPTION_SEND_DISCONNECT);
3191 free_neighbour (n); 3209 n->is_connected = GNUNET_NO;
3192} 3210}
3193 3211
3194 3212
diff --git a/src/core/test_core_api_peer1.conf b/src/core/test_core_api_peer1.conf
index af7605222..cc9098e02 100644
--- a/src/core/test_core_api_peer1.conf
+++ b/src/core/test_core_api_peer1.conf
@@ -36,11 +36,12 @@ PORT = 12469
36 36
37[core] 37[core]
38PORT = 12470 38PORT = 12470
39#PREFIX = xterm -T core1 -e valgrind --tool=memcheck 39#PREFIX = valgrind --tool=memcheck
40#OPTIONS = -l log-core-1 40#OPTIONS = -l log-core-1
41#PREFIX = xterm -e xterm -T core1 -e gdb --args 41#PREFIX = xterm -e xterm -T core1 -e gdb --args
42#PREFIX = xterm -T core1 -e 42#PREFIX = xterm -T core1 -e
43DEBUG = NO 43DEBUG = NO
44#BINARY=/home/grothoff/bin/gnunet-service-core
44 45
45[testing] 46[testing]
46WEAKRANDOM = YES 47WEAKRANDOM = YES
diff --git a/src/core/test_core_api_peer2.conf b/src/core/test_core_api_peer2.conf
index 687e8813c..1428ef9d9 100644
--- a/src/core/test_core_api_peer2.conf
+++ b/src/core/test_core_api_peer2.conf
@@ -37,8 +37,9 @@ PORT = 22469
37[core] 37[core]
38PORT = 22470 38PORT = 22470
39#PREFIX = xterm -T core2 -e 39#PREFIX = xterm -T core2 -e
40#PREFIX = xterm -T core2 -e valgrind --tool=memcheck 40#PREFIX = valgrind --tool=memcheck
41DEBUG = NO 41DEBUG = NO
42#BINARY=/home/grothoff/bin/gnunet-service-core
42 43
43[testing] 44[testing]
44WEAKRANDOM = YES 45WEAKRANDOM = YES
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c
index 854eef773..f94ca3ef8 100644
--- a/src/transport/gnunet-service-transport.c
+++ b/src/transport/gnunet-service-transport.c
@@ -290,11 +290,11 @@ struct TransportPlugin
290 290
291}; 291};
292 292
293struct NeighborList; 293struct NeighbourList;
294 294
295/** 295/**
296 * For each neighbor we keep a list of messages 296 * For each neighbour we keep a list of messages
297 * that we still want to transmit to the neighbor. 297 * that we still want to transmit to the neighbour.
298 */ 298 */
299struct MessageQueue 299struct MessageQueue
300{ 300{
@@ -333,9 +333,9 @@ struct MessageQueue
333 struct ForeignAddressList *specific_address; 333 struct ForeignAddressList *specific_address;
334 334
335 /** 335 /**
336 * Peer ID of the Neighbor this entry belongs to. 336 * Peer ID of the Neighbour this entry belongs to.
337 */ 337 */
338 struct GNUNET_PeerIdentity neighbor_id; 338 struct GNUNET_PeerIdentity neighbour_id;
339 339
340 /** 340 /**
341 * Plugin that we used for the transmission. 341 * Plugin that we used for the transmission.
@@ -344,6 +344,11 @@ struct MessageQueue
344 struct TransportPlugin *plugin; 344 struct TransportPlugin *plugin;
345 345
346 /** 346 /**
347 * At what time should we fail?
348 */
349 struct GNUNET_TIME_Absolute timeout;
350
351 /**
347 * Internal message of the transport system that should not be 352 * Internal message of the transport system that should not be
348 * included in the usual SEND-SEND_OK transmission confirmation 353 * included in the usual SEND-SEND_OK transmission confirmation
349 * traffic management scheme. Typically, "internal_msg" will 354 * traffic management scheme. Typically, "internal_msg" will
@@ -361,7 +366,7 @@ struct MessageQueue
361 366
362 367
363/** 368/**
364 * For a given Neighbor, which plugins are available 369 * For a given Neighbour, which plugins are available
365 * to talk to this peer and what are their costs? 370 * to talk to this peer and what are their costs?
366 */ 371 */
367struct ReadyList 372struct ReadyList
@@ -387,15 +392,15 @@ struct ReadyList
387 392
388 393
389/** 394/**
390 * Entry in linked list of all of our current neighbors. 395 * Entry in linked list of all of our current neighbours.
391 */ 396 */
392struct NeighborList 397struct NeighbourList
393{ 398{
394 399
395 /** 400 /**
396 * This is a linked list. 401 * This is a linked list.
397 */ 402 */
398 struct NeighborList *next; 403 struct NeighbourList *next;
399 404
400 /** 405 /**
401 * Which of our transports is connected to this peer 406 * Which of our transports is connected to this peer
@@ -416,7 +421,7 @@ struct NeighborList
416 struct MessageQueue *messages_tail; 421 struct MessageQueue *messages_tail;
417 422
418 /** 423 /**
419 * Identity of this neighbor. 424 * Identity of this neighbour.
420 */ 425 */
421 struct GNUNET_PeerIdentity id; 426 struct GNUNET_PeerIdentity id;
422 427
@@ -427,6 +432,12 @@ struct NeighborList
427 GNUNET_SCHEDULER_TaskIdentifier timeout_task; 432 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
428 433
429 /** 434 /**
435 * ID of task scheduled to run when we should retry transmitting
436 * the head of the message queue.
437 */
438 GNUNET_SCHEDULER_TaskIdentifier retry_task;
439
440 /**
430 * How long until we should consider this peer dead 441 * How long until we should consider this peer dead
431 * (if we don't receive another message in the 442 * (if we don't receive another message in the
432 * meantime)? 443 * meantime)?
@@ -443,7 +454,7 @@ struct NeighborList
443 * this particular peer. This latency may have been calculated 454 * this particular peer. This latency may have been calculated
444 * over multiple transports. This value reflects how long it took 455 * over multiple transports. This value reflects how long it took
445 * us to receive a response when SENDING via this particular 456 * us to receive a response when SENDING via this particular
446 * transport/neighbor/address combination! 457 * transport/neighbour/address combination!
447 * 458 *
448 * FIXME: we need to periodically send PINGs to update this 459 * FIXME: we need to periodically send PINGs to update this
449 * latency (at least more often than the current "huge" (11h?) 460 * latency (at least more often than the current "huge" (11h?)
@@ -463,7 +474,7 @@ struct NeighborList
463 uint64_t last_received; 474 uint64_t last_received;
464 475
465 /** 476 /**
466 * Global quota for inbound traffic for the neighbor in bytes/ms. 477 * Global quota for inbound traffic for the neighbour in bytes/ms.
467 */ 478 */
468 uint32_t quota_in; 479 uint32_t quota_in;
469 480
@@ -476,7 +487,7 @@ struct NeighborList
476 unsigned int quota_violation_count; 487 unsigned int quota_violation_count;
477 488
478 /** 489 /**
479 * Have we seen an PONG from this neighbor in the past (and 490 * Have we seen an PONG from this neighbour in the past (and
480 * not had a disconnect since)? 491 * not had a disconnect since)?
481 */ 492 */
482 int received_pong; 493 int received_pong;
@@ -708,7 +719,7 @@ struct CheckHelloValidatedContext
708static struct GNUNET_HELLO_Message *our_hello; 719static struct GNUNET_HELLO_Message *our_hello;
709 720
710/** 721/**
711 * "version" of "our_hello". Used to see if a given neighbor has 722 * "version" of "our_hello". Used to see if a given neighbour has
712 * already been sent the latest version of our HELLO message. 723 * already been sent the latest version of our HELLO message.
713 */ 724 */
714static unsigned int our_hello_version; 725static unsigned int our_hello_version;
@@ -754,12 +765,12 @@ static struct TransportPlugin *plugins;
754static struct GNUNET_SERVER_Handle *server; 765static struct GNUNET_SERVER_Handle *server;
755 766
756/** 767/**
757 * All known neighbors and their HELLOs. 768 * All known neighbours and their HELLOs.
758 */ 769 */
759static struct NeighborList *neighbors; 770static struct NeighbourList *neighbours;
760 771
761/** 772/**
762 * Number of neighbors we'd like to have. 773 * Number of neighbours we'd like to have.
763 */ 774 */
764static uint32_t max_connect_per_transport; 775static uint32_t max_connect_per_transport;
765 776
@@ -782,41 +793,41 @@ static struct GNUNET_CONTAINER_MultiHashMap *validation_map;
782 793
783 794
784/** 795/**
785 * The peer specified by the given neighbor has timed-out or a plugin 796 * The peer specified by the given neighbour has timed-out or a plugin
786 * has disconnected. We may either need to do nothing (other plugins 797 * has disconnected. We may either need to do nothing (other plugins
787 * still up), or trigger a full disconnect and clean up. This 798 * still up), or trigger a full disconnect and clean up. This
788 * function updates our state and do the necessary notifications. 799 * function updates our state and do the necessary notifications.
789 * Also notifies our clients that the neighbor is now officially 800 * Also notifies our clients that the neighbour is now officially
790 * gone. 801 * gone.
791 * 802 *
792 * @param n the neighbor list entry for the peer 803 * @param n the neighbour list entry for the peer
793 * @param check should we just check if all plugins 804 * @param check should we just check if all plugins
794 * disconnected or must we ask all plugins to 805 * disconnected or must we ask all plugins to
795 * disconnect? 806 * disconnect?
796 */ 807 */
797static void disconnect_neighbor (struct NeighborList *n, int check); 808static void disconnect_neighbour (struct NeighbourList *n, int check);
798 809
799/** 810/**
800 * Check the ready list for the given neighbor and if a plugin is 811 * Check the ready list for the given neighbour and if a plugin is
801 * ready for transmission (and if we have a message), do so! 812 * ready for transmission (and if we have a message), do so!
802 * 813 *
803 * @param neighbor target peer for which to transmit 814 * @param neighbour target peer for which to transmit
804 */ 815 */
805static void try_transmission_to_peer (struct NeighborList *neighbor); 816static void try_transmission_to_peer (struct NeighbourList *neighbour);
806 817
807 818
808/** 819/**
809 * Find an entry in the neighbor list for a particular peer. 820 * Find an entry in the neighbour list for a particular peer.
810 * if sender_address is not specified (NULL) then return the 821 * if sender_address is not specified (NULL) then return the
811 * first matching entry. If sender_address is specified, then 822 * first matching entry. If sender_address is specified, then
812 * make sure that the address and address_len also matches. 823 * make sure that the address and address_len also matches.
813 * 824 *
814 * @return NULL if not found. 825 * @return NULL if not found.
815 */ 826 */
816static struct NeighborList * 827static struct NeighbourList *
817find_neighbor (const struct GNUNET_PeerIdentity *key) 828find_neighbour (const struct GNUNET_PeerIdentity *key)
818{ 829{
819 struct NeighborList *head = neighbors; 830 struct NeighbourList *head = neighbours;
820 831
821 while ((head != NULL) && 832 while ((head != NULL) &&
822 (0 != memcmp (key, &head->id, sizeof (struct GNUNET_PeerIdentity)))) 833 (0 != memcmp (key, &head->id, sizeof (struct GNUNET_PeerIdentity))))
@@ -841,10 +852,10 @@ find_transport (const char *short_name)
841 852
842 853
843/** 854/**
844 * Update the quota values for the given neighbor now. 855 * Update the quota values for the given neighbour now.
845 */ 856 */
846static void 857static void
847update_quota (struct NeighborList *n) 858update_quota (struct NeighbourList *n)
848{ 859{
849 struct GNUNET_TIME_Relative delta; 860 struct GNUNET_TIME_Relative delta;
850 uint64_t allowed; 861 uint64_t allowed;
@@ -1010,15 +1021,15 @@ transmit_to_client (struct TransportClient *client,
1010 1021
1011/** 1022/**
1012 * Transmit a 'SEND_OK' notification to the given client for the 1023 * Transmit a 'SEND_OK' notification to the given client for the
1013 * given neighbor. 1024 * given neighbour.
1014 * 1025 *
1015 * @param client who to notify 1026 * @param client who to notify
1016 * @param n neighbor to notify about 1027 * @param n neighbour to notify about
1017 * @param result status code for the transmission request 1028 * @param result status code for the transmission request
1018 */ 1029 */
1019static void 1030static void
1020transmit_send_ok (struct TransportClient *client, 1031transmit_send_ok (struct TransportClient *client,
1021 struct NeighborList *n, 1032 struct NeighbourList *n,
1022 int result) 1033 int result)
1023{ 1034{
1024 struct SendOkMessage send_ok_msg; 1035 struct SendOkMessage send_ok_msg;
@@ -1052,9 +1063,9 @@ transmit_send_continuation (void *cls,
1052 int result) 1063 int result)
1053{ 1064{
1054 struct MessageQueue *mq = cls; 1065 struct MessageQueue *mq = cls;
1055 struct NeighborList *n; 1066 struct NeighbourList *n;
1056 1067
1057 n = find_neighbor(&mq->neighbor_id); 1068 n = find_neighbour(&mq->neighbour_id);
1058 GNUNET_assert (n != NULL); 1069 GNUNET_assert (n != NULL);
1059 if (mq->specific_address != NULL) 1070 if (mq->specific_address != NULL)
1060 { 1071 {
@@ -1077,23 +1088,23 @@ transmit_send_continuation (void *cls,
1077 GNUNET_free (mq); 1088 GNUNET_free (mq);
1078 try_transmission_to_peer (n); 1089 try_transmission_to_peer (n);
1079 if (result != GNUNET_OK) 1090 if (result != GNUNET_OK)
1080 disconnect_neighbor (n, GNUNET_YES); 1091 disconnect_neighbour (n, GNUNET_YES);
1081} 1092}
1082 1093
1083 1094
1084/** 1095/**
1085 * Find an address in any of the available transports for 1096 * Find an address in any of the available transports for
1086 * the given neighbor that would be good for message 1097 * the given neighbour that would be good for message
1087 * transmission. This is essentially the transport selection 1098 * transmission. This is essentially the transport selection
1088 * routine. 1099 * routine.
1089 * 1100 *
1090 * @param neighbor for whom to select an address 1101 * @param neighbour for whom to select an address
1091 * @return selected address, NULL if we have none 1102 * @return selected address, NULL if we have none
1092 */ 1103 */
1093struct ForeignAddressList * 1104struct ForeignAddressList *
1094find_ready_address(struct NeighborList *neighbor) 1105find_ready_address(struct NeighbourList *neighbour)
1095{ 1106{
1096 struct ReadyList *head = neighbor->plugins; 1107 struct ReadyList *head = neighbour->plugins;
1097 struct ForeignAddressList *addresses; 1108 struct ForeignAddressList *addresses;
1098 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get (); 1109 struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
1099 struct ForeignAddressList *best_address; 1110 struct ForeignAddressList *best_address;
@@ -1110,7 +1121,7 @@ find_ready_address(struct NeighborList *neighbor)
1110#if DEBUG_TRANSPORT 1121#if DEBUG_TRANSPORT
1111 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1122 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1112 "Marking long-time inactive connection to `%4s' as down.\n", 1123 "Marking long-time inactive connection to `%4s' as down.\n",
1113 GNUNET_i2s (&neighbor->id)); 1124 GNUNET_i2s (&neighbour->id));
1114#endif 1125#endif
1115 addresses->connected = GNUNET_NO; 1126 addresses->connected = GNUNET_NO;
1116 } 1127 }
@@ -1147,41 +1158,69 @@ find_ready_address(struct NeighborList *neighbor)
1147 1158
1148 1159
1149/** 1160/**
1150 * Check the ready list for the given neighbor and if a plugin is 1161 * We should re-try transmitting to the given peer,
1162 * hopefully we've learned something in the meantime.
1163 */
1164static void
1165retry_transmission_task (void *cls,
1166 const struct GNUNET_SCHEDULER_TaskContext *tc)
1167{
1168 struct NeighbourList *n = cls;
1169
1170 n->retry_task = GNUNET_SCHEDULER_NO_TASK;
1171 try_transmission_to_peer (n);
1172}
1173
1174
1175/**
1176 * Check the ready list for the given neighbour and if a plugin is
1151 * ready for transmission (and if we have a message), do so! 1177 * ready for transmission (and if we have a message), do so!
1152 * 1178 *
1153 * @param neighbor target peer for which to transmit 1179 * @param neighbour target peer for which to transmit
1154 */ 1180 */
1155static void 1181static void
1156try_transmission_to_peer (struct NeighborList *neighbor) 1182try_transmission_to_peer (struct NeighbourList *neighbour)
1157{ 1183{
1158 struct GNUNET_TIME_Relative min_latency; 1184 struct GNUNET_TIME_Relative min_latency;
1159 struct ReadyList *rl; 1185 struct ReadyList *rl;
1160 struct MessageQueue *mq; 1186 struct MessageQueue *mq;
1187 struct GNUNET_TIME_Relative timeout;
1161 1188
1162 if (neighbor->messages_head == NULL) 1189 if (neighbour->messages_head == NULL)
1163 return; /* nothing to do */ 1190 return; /* nothing to do */
1164 min_latency = GNUNET_TIME_UNIT_FOREVER_REL; 1191 min_latency = GNUNET_TIME_UNIT_FOREVER_REL;
1165 rl = NULL; 1192 rl = NULL;
1166 mq = neighbor->messages_head; 1193 mq = neighbour->messages_head;
1167 /* FIXME: support bi-directional use of TCP */ 1194 /* FIXME: support bi-directional use of TCP */
1168 if (mq->specific_address == NULL) 1195 if (mq->specific_address == NULL)
1169 mq->specific_address = find_ready_address(neighbor); 1196 mq->specific_address = find_ready_address(neighbour);
1170 GNUNET_CONTAINER_DLL_remove (neighbor->messages_head, 1197 GNUNET_CONTAINER_DLL_remove (neighbour->messages_head,
1171 neighbor->messages_tail, 1198 neighbour->messages_tail,
1172 mq); 1199 mq);
1173 if (mq->specific_address == NULL) 1200 if (mq->specific_address == NULL)
1174 { 1201 {
1202 timeout = GNUNET_TIME_absolute_get_remaining (mq->timeout);
1203 if (timeout.value == 0)
1204 {
1175#if DEBUG_TRANSPORT 1205#if DEBUG_TRANSPORT
1176 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1206 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1177 "No destination address available to transmit message of size %u to peer `%4s'\n", 1207 "No destination address available to transmit message of size %u to peer `%4s'\n",
1178 mq->message_buf_size, 1208 mq->message_buf_size,
1179 GNUNET_i2s (&mq->neighbor_id)); 1209 GNUNET_i2s (&mq->neighbour_id));
1180#endif 1210#endif
1181 if (mq->client != NULL) 1211 if (mq->client != NULL)
1182 transmit_send_ok (mq->client, neighbor, GNUNET_NO); 1212 transmit_send_ok (mq->client, neighbour, GNUNET_NO);
1183 GNUNET_free (mq); 1213 GNUNET_free (mq);
1184 return; /* nobody ready */ 1214 return; /* nobody ready */
1215 }
1216 if (neighbour->retry_task != GNUNET_SCHEDULER_NO_TASK)
1217 GNUNET_SCHEDULER_cancel (sched,
1218 neighbour->retry_task);
1219 neighbour->retry_task = GNUNET_SCHEDULER_add_delayed (sched,
1220 timeout,
1221 &retry_transmission_task,
1222 neighbour);
1223 return;
1185 } 1224 }
1186 if (mq->specific_address->connected == GNUNET_NO) 1225 if (mq->specific_address->connected == GNUNET_NO)
1187 mq->specific_address->connect_attempts++; 1226 mq->specific_address->connect_attempts++;
@@ -1193,13 +1232,13 @@ try_transmission_to_peer (struct NeighborList *neighbor)
1193 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1232 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1194 "Sending message of size %u for `%4s' to `%s' via plugin `%s'\n", 1233 "Sending message of size %u for `%4s' to `%s' via plugin `%s'\n",
1195 mq->message_buf_size, 1234 mq->message_buf_size,
1196 GNUNET_i2s (&neighbor->id), 1235 GNUNET_i2s (&neighbour->id),
1197 GNUNET_a2s (mq->specific_address->addr, 1236 GNUNET_a2s (mq->specific_address->addr,
1198 mq->specific_address->addrlen), 1237 mq->specific_address->addrlen),
1199 rl->plugin->short_name); 1238 rl->plugin->short_name);
1200#endif 1239#endif
1201 rl->plugin->api->send (rl->plugin->api->cls, 1240 rl->plugin->api->send (rl->plugin->api->cls,
1202 &mq->neighbor_id, 1241 &mq->neighbour_id,
1203 mq->message_buf, 1242 mq->message_buf,
1204 mq->message_buf_size, 1243 mq->message_buf_size,
1205 mq->priority, 1244 mq->priority,
@@ -1217,19 +1256,21 @@ try_transmission_to_peer (struct NeighborList *neighbor)
1217 * @param client source of the transmission request (can be NULL) 1256 * @param client source of the transmission request (can be NULL)
1218 * @param peer_address ForeignAddressList where we should send this message 1257 * @param peer_address ForeignAddressList where we should send this message
1219 * @param priority how important is the message 1258 * @param priority how important is the message
1259 * @param timeout how long do we have to transmit?
1220 * @param message_buf message(s) to send GNUNET_MessageHeader(s) 1260 * @param message_buf message(s) to send GNUNET_MessageHeader(s)
1221 * @param message_buf_size total size of all messages in message_buf 1261 * @param message_buf_size total size of all messages in message_buf
1222 * @param is_internal is this an internal message; these are pre-pended and 1262 * @param is_internal is this an internal message; these are pre-pended and
1223 * also do not count for plugins being "ready" to transmit 1263 * also do not count for plugins being "ready" to transmit
1224 * @param neighbor handle to the neighbor for transmission 1264 * @param neighbour handle to the neighbour for transmission
1225 */ 1265 */
1226static void 1266static void
1227transmit_to_peer (struct TransportClient *client, 1267transmit_to_peer (struct TransportClient *client,
1228 struct ForeignAddressList *peer_address, 1268 struct ForeignAddressList *peer_address,
1229 unsigned int priority, 1269 unsigned int priority,
1270 struct GNUNET_TIME_Relative timeout,
1230 const char *message_buf, 1271 const char *message_buf,
1231 size_t message_buf_size, 1272 size_t message_buf_size,
1232 int is_internal, struct NeighborList *neighbor) 1273 int is_internal, struct NeighbourList *neighbour)
1233{ 1274{
1234 struct MessageQueue *mq; 1275 struct MessageQueue *mq;
1235 1276
@@ -1237,7 +1278,7 @@ transmit_to_peer (struct TransportClient *client,
1237 if (client != NULL) 1278 if (client != NULL)
1238 { 1279 {
1239 /* check for duplicate submission */ 1280 /* check for duplicate submission */
1240 mq = neighbor->messages_head; 1281 mq = neighbour->messages_head;
1241 while (NULL != mq) 1282 while (NULL != mq)
1242 { 1283 {
1243 if (mq->client == client) 1284 if (mq->client == client)
@@ -1257,19 +1298,20 @@ transmit_to_peer (struct TransportClient *client,
1257 memcpy (&mq[1], message_buf, message_buf_size); 1298 memcpy (&mq[1], message_buf, message_buf_size);
1258 mq->message_buf = (const char*) &mq[1]; 1299 mq->message_buf = (const char*) &mq[1];
1259 mq->message_buf_size = message_buf_size; 1300 mq->message_buf_size = message_buf_size;
1260 memcpy(&mq->neighbor_id, &neighbor->id, sizeof(struct GNUNET_PeerIdentity)); 1301 memcpy(&mq->neighbour_id, &neighbour->id, sizeof(struct GNUNET_PeerIdentity));
1261 mq->internal_msg = is_internal; 1302 mq->internal_msg = is_internal;
1262 mq->priority = priority; 1303 mq->priority = priority;
1304 mq->timeout = GNUNET_TIME_relative_to_absolute (timeout);
1263 if (is_internal) 1305 if (is_internal)
1264 GNUNET_CONTAINER_DLL_insert (neighbor->messages_head, 1306 GNUNET_CONTAINER_DLL_insert (neighbour->messages_head,
1265 neighbor->messages_tail, 1307 neighbour->messages_tail,
1266 mq); 1308 mq);
1267 else 1309 else
1268 GNUNET_CONTAINER_DLL_insert_after (neighbor->messages_head, 1310 GNUNET_CONTAINER_DLL_insert_after (neighbour->messages_head,
1269 neighbor->messages_tail, 1311 neighbour->messages_tail,
1270 neighbor->messages_tail, 1312 neighbour->messages_tail,
1271 mq); 1313 mq);
1272 try_transmission_to_peer (neighbor); 1314 try_transmission_to_peer (neighbour);
1273} 1315}
1274 1316
1275 1317
@@ -1321,7 +1363,7 @@ refresh_hello ()
1321{ 1363{
1322 struct GNUNET_HELLO_Message *hello; 1364 struct GNUNET_HELLO_Message *hello;
1323 struct TransportClient *cpos; 1365 struct TransportClient *cpos;
1324 struct NeighborList *npos; 1366 struct NeighbourList *npos;
1325 struct GeneratorContext gc; 1367 struct GeneratorContext gc;
1326 1368
1327 gc.plug_pos = plugins; 1369 gc.plug_pos = plugins;
@@ -1345,15 +1387,16 @@ refresh_hello ()
1345 our_hello = hello; 1387 our_hello = hello;
1346 our_hello_version++; 1388 our_hello_version++;
1347 GNUNET_PEERINFO_add_peer (cfg, sched, &my_identity, our_hello); 1389 GNUNET_PEERINFO_add_peer (cfg, sched, &my_identity, our_hello);
1348 npos = neighbors; 1390 npos = neighbours;
1349 while (npos != NULL) 1391 while (npos != NULL)
1350 { 1392 {
1351#if DEBUG_TRANSPORT 1393#if DEBUG_TRANSPORT
1352 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, 1394 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
1353 "Transmitting updated `%s' to neighbor `%4s'\n", 1395 "Transmitting updated `%s' to neighbour `%4s'\n",
1354 "HELLO", GNUNET_i2s (&npos->id)); 1396 "HELLO", GNUNET_i2s (&npos->id));
1355#endif 1397#endif
1356 transmit_to_peer (NULL, NULL, 0, 1398 transmit_to_peer (NULL, NULL, 0,
1399 HELLO_ADDRESS_EXPIRATION,
1357 (const char *) our_hello, 1400 (const char *) our_hello,
1358 GNUNET_HELLO_size(our_hello), 1401 GNUNET_HELLO_size(our_hello),
1359 GNUNET_NO, npos); 1402 GNUNET_NO, npos);
@@ -1559,14 +1602,14 @@ notify_clients_disconnect (const struct GNUNET_PeerIdentity *peer)
1559 * Find a ForeignAddressList entry for the given neighbour 1602 * Find a ForeignAddressList entry for the given neighbour
1560 * that matches the given address and transport. 1603 * that matches the given address and transport.
1561 * 1604 *
1562 * @param neighbor which peer we care about 1605 * @param neighbour which peer we care about
1563 * @param tname name of the transport plugin 1606 * @param tname name of the transport plugin
1564 * @param addr binary address 1607 * @param addr binary address
1565 * @param addrlen length of addr 1608 * @param addrlen length of addr
1566 * @return NULL if no such entry exists 1609 * @return NULL if no such entry exists
1567 */ 1610 */
1568static struct ForeignAddressList * 1611static struct ForeignAddressList *
1569find_peer_address(struct NeighborList *neighbor, 1612find_peer_address(struct NeighbourList *neighbour,
1570 const char *tname, 1613 const char *tname,
1571 const char *addr, 1614 const char *addr,
1572 size_t addrlen) 1615 size_t addrlen)
@@ -1574,7 +1617,7 @@ find_peer_address(struct NeighborList *neighbor,
1574 struct ReadyList *head; 1617 struct ReadyList *head;
1575 struct ForeignAddressList *address_head; 1618 struct ForeignAddressList *address_head;
1576 1619
1577 head = neighbor->plugins; 1620 head = neighbour->plugins;
1578 while (head != NULL) 1621 while (head != NULL)
1579 { 1622 {
1580 if (0 == strcmp (tname, head->plugin->short_name)) 1623 if (0 == strcmp (tname, head->plugin->short_name))
@@ -1594,17 +1637,17 @@ find_peer_address(struct NeighborList *neighbor,
1594 1637
1595 1638
1596/** 1639/**
1597 * Get the peer address struct for the given neighbor and 1640 * Get the peer address struct for the given neighbour and
1598 * address. If it doesn't yet exist, create it. 1641 * address. If it doesn't yet exist, create it.
1599 * 1642 *
1600 * @param neighbor which peer we care about 1643 * @param neighbour which peer we care about
1601 * @param tname name of the transport plugin 1644 * @param tname name of the transport plugin
1602 * @param addr binary address 1645 * @param addr binary address
1603 * @param addrlen length of addr 1646 * @param addrlen length of addr
1604 * @return NULL if we do not have a transport plugin for 'tname' 1647 * @return NULL if we do not have a transport plugin for 'tname'
1605 */ 1648 */
1606static struct ForeignAddressList * 1649static struct ForeignAddressList *
1607add_peer_address(struct NeighborList *neighbor, 1650add_peer_address(struct NeighbourList *neighbour,
1608 const char *tname, 1651 const char *tname,
1609 const char *addr, 1652 const char *addr,
1610 size_t addrlen) 1653 size_t addrlen)
@@ -1612,10 +1655,10 @@ add_peer_address(struct NeighborList *neighbor,
1612 struct ReadyList *head; 1655 struct ReadyList *head;
1613 struct ForeignAddressList *ret; 1656 struct ForeignAddressList *ret;
1614 1657
1615 ret = find_peer_address (neighbor, tname, addr, addrlen); 1658 ret = find_peer_address (neighbour, tname, addr, addrlen);
1616 if (ret != NULL) 1659 if (ret != NULL)
1617 return ret; 1660 return ret;
1618 head = neighbor->plugins; 1661 head = neighbour->plugins;
1619 while (head != NULL) 1662 while (head != NULL)
1620 { 1663 {
1621 if (0 == strcmp (tname, head->plugin->short_name)) 1664 if (0 == strcmp (tname, head->plugin->short_name))
@@ -1711,7 +1754,7 @@ check_pending_validation (void *cls,
1711 unsigned int challenge = ntohl(pong->challenge); 1754 unsigned int challenge = ntohl(pong->challenge);
1712 struct GNUNET_HELLO_Message *hello; 1755 struct GNUNET_HELLO_Message *hello;
1713 struct GNUNET_PeerIdentity target; 1756 struct GNUNET_PeerIdentity target;
1714 struct NeighborList *n; 1757 struct NeighbourList *n;
1715 struct ForeignAddressList *fal; 1758 struct ForeignAddressList *fal;
1716 1759
1717 if (ve->challenge != challenge) 1760 if (ve->challenge != challenge)
@@ -1738,7 +1781,7 @@ check_pending_validation (void *cls,
1738 &target, 1781 &target,
1739 hello); 1782 hello);
1740 GNUNET_free (hello); 1783 GNUNET_free (hello);
1741 n = find_neighbor (&target); 1784 n = find_neighbour (&target);
1742 if (n != NULL) 1785 if (n != NULL)
1743 { 1786 {
1744 fal = add_peer_address (n, ve->transport_name, 1787 fal = add_peer_address (n, ve->transport_name,
@@ -1757,6 +1800,13 @@ check_pending_validation (void *cls,
1757 notify_clients_connect (&target, n->latency, n->distance); 1800 notify_clients_connect (&target, n->latency, n->distance);
1758 n->received_pong = GNUNET_YES; 1801 n->received_pong = GNUNET_YES;
1759 } 1802 }
1803 if (n->retry_task != GNUNET_SCHEDULER_NO_TASK)
1804 {
1805 GNUNET_SCHEDULER_cancel (sched,
1806 n->retry_task);
1807 n->retry_task = GNUNET_SCHEDULER_NO_TASK;
1808 try_transmission_to_peer (n);
1809 }
1760 } 1810 }
1761 1811
1762 /* clean up validation entry */ 1812 /* clean up validation entry */
@@ -1835,39 +1885,39 @@ handle_pong (void *cls, const struct GNUNET_MessageHeader *message,
1835 1885
1836 1886
1837static void 1887static void
1838neighbor_timeout_task (void *cls, 1888neighbour_timeout_task (void *cls,
1839 const struct GNUNET_SCHEDULER_TaskContext *tc) 1889 const struct GNUNET_SCHEDULER_TaskContext *tc)
1840{ 1890{
1841 struct NeighborList *n = cls; 1891 struct NeighbourList *n = cls;
1842 1892
1843#if DEBUG_TRANSPORT 1893#if DEBUG_TRANSPORT
1844 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, 1894 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
1845 "Neighbor `%4s' has timed out!\n", GNUNET_i2s (&n->id)); 1895 "Neighbour `%4s' has timed out!\n", GNUNET_i2s (&n->id));
1846#endif 1896#endif
1847 n->timeout_task = GNUNET_SCHEDULER_NO_TASK; 1897 n->timeout_task = GNUNET_SCHEDULER_NO_TASK;
1848 disconnect_neighbor (n, GNUNET_NO); 1898 disconnect_neighbour (n, GNUNET_NO);
1849} 1899}
1850 1900
1851 1901
1852/** 1902/**
1853 * Create a fresh entry in our neighbor list for the given peer. 1903 * Create a fresh entry in our neighbour list for the given peer.
1854 * Will try to transmit our current HELLO to the new neighbor. Also 1904 * Will try to transmit our current HELLO to the new neighbour. Also
1855 * notifies our clients about the new "connection". 1905 * notifies our clients about the new "connection".
1856 * 1906 *
1857 * @param peer the peer for which we create the entry 1907 * @param peer the peer for which we create the entry
1858 * @return the new neighbor list entry 1908 * @return the new neighbour list entry
1859 */ 1909 */
1860static struct NeighborList * 1910static struct NeighbourList *
1861setup_new_neighbor (const struct GNUNET_PeerIdentity *peer) 1911setup_new_neighbour (const struct GNUNET_PeerIdentity *peer)
1862{ 1912{
1863 struct NeighborList *n; 1913 struct NeighbourList *n;
1864 struct TransportPlugin *tp; 1914 struct TransportPlugin *tp;
1865 struct ReadyList *rl; 1915 struct ReadyList *rl;
1866 1916
1867 GNUNET_assert (our_hello != NULL); 1917 GNUNET_assert (our_hello != NULL);
1868 n = GNUNET_malloc (sizeof (struct NeighborList)); 1918 n = GNUNET_malloc (sizeof (struct NeighbourList));
1869 n->next = neighbors; 1919 n->next = neighbours;
1870 neighbors = n; 1920 neighbours = n;
1871 n->id = *peer; 1921 n->id = *peer;
1872 n->last_quota_update = GNUNET_TIME_absolute_get (); 1922 n->last_quota_update = GNUNET_TIME_absolute_get ();
1873 n->peer_timeout = 1923 n->peer_timeout =
@@ -1891,8 +1941,9 @@ setup_new_neighbor (const struct GNUNET_PeerIdentity *peer)
1891 n->distance = -1; 1941 n->distance = -1;
1892 n->timeout_task = GNUNET_SCHEDULER_add_delayed (sched, 1942 n->timeout_task = GNUNET_SCHEDULER_add_delayed (sched,
1893 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 1943 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
1894 &neighbor_timeout_task, n); 1944 &neighbour_timeout_task, n);
1895 transmit_to_peer (NULL, NULL, 0, 1945 transmit_to_peer (NULL, NULL, 0,
1946 HELLO_ADDRESS_EXPIRATION,
1896 (const char *) our_hello, GNUNET_HELLO_size(our_hello), 1947 (const char *) our_hello, GNUNET_HELLO_size(our_hello),
1897 GNUNET_NO, n); 1948 GNUNET_NO, n);
1898 return n; 1949 return n;
@@ -2004,7 +2055,7 @@ run_validation (void *cls,
2004 struct GNUNET_PeerIdentity id; 2055 struct GNUNET_PeerIdentity id;
2005 struct TransportPlugin *tp; 2056 struct TransportPlugin *tp;
2006 struct ValidationEntry *va; 2057 struct ValidationEntry *va;
2007 struct NeighborList *neighbor; 2058 struct NeighbourList *neighbour;
2008 struct ForeignAddressList *peer_address; 2059 struct ForeignAddressList *peer_address;
2009 struct TransportPingMessage ping; 2060 struct TransportPingMessage ping;
2010 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pk; 2061 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pk;
@@ -2068,10 +2119,10 @@ run_validation (void *cls,
2068 &id.hashPubKey, 2119 &id.hashPubKey,
2069 va, 2120 va,
2070 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 2121 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
2071 neighbor = find_neighbor(&id); 2122 neighbour = find_neighbour(&id);
2072 if (neighbor == NULL) 2123 if (neighbour == NULL)
2073 neighbor = setup_new_neighbor(&id); 2124 neighbour = setup_new_neighbour(&id);
2074 peer_address = add_peer_address(neighbor, tname, addr, addrlen); 2125 peer_address = add_peer_address(neighbour, tname, addr, addrlen);
2075 GNUNET_assert(peer_address != NULL); 2126 GNUNET_assert(peer_address != NULL);
2076 hello_size = GNUNET_HELLO_size(our_hello); 2127 hello_size = GNUNET_HELLO_size(our_hello);
2077 tsize = sizeof(struct TransportPingMessage) + hello_size; 2128 tsize = sizeof(struct TransportPingMessage) + hello_size;
@@ -2095,8 +2146,9 @@ run_validation (void *cls,
2095#endif 2146#endif
2096 transmit_to_peer (NULL, peer_address, 2147 transmit_to_peer (NULL, peer_address,
2097 GNUNET_SCHEDULER_PRIORITY_DEFAULT, 2148 GNUNET_SCHEDULER_PRIORITY_DEFAULT,
2149 HELLO_VERIFICATION_TIMEOUT,
2098 message_buf, tsize, 2150 message_buf, tsize,
2099 GNUNET_YES, neighbor); 2151 GNUNET_YES, neighbour);
2100 GNUNET_free(message_buf); 2152 GNUNET_free(message_buf);
2101 return GNUNET_OK; 2153 return GNUNET_OK;
2102} 2154}
@@ -2106,7 +2158,7 @@ run_validation (void *cls,
2106 * Add the given address to the list of foreign addresses 2158 * Add the given address to the list of foreign addresses
2107 * available for the given peer (check for duplicates). 2159 * available for the given peer (check for duplicates).
2108 * 2160 *
2109 * @param cls the respective 'struct NeighborList' to update 2161 * @param cls the respective 'struct NeighbourList' to update
2110 * @param tname name of the transport 2162 * @param tname name of the transport
2111 * @param expiration expiration time 2163 * @param expiration expiration time
2112 * @param addr the address 2164 * @param addr the address
@@ -2119,7 +2171,7 @@ add_to_foreign_address_list (void *cls,
2119 struct GNUNET_TIME_Absolute expiration, 2171 struct GNUNET_TIME_Absolute expiration,
2120 const void *addr, size_t addrlen) 2172 const void *addr, size_t addrlen)
2121{ 2173{
2122 struct NeighborList *n = cls; 2174 struct NeighbourList *n = cls;
2123 struct ForeignAddressList *fal; 2175 struct ForeignAddressList *fal;
2124 2176
2125 fal = find_peer_address (n, tname, addr, addrlen); 2177 fal = find_peer_address (n, tname, addr, addrlen);
@@ -2162,7 +2214,7 @@ check_hello_validated (void *cls,
2162 struct GNUNET_HELLO_Message *plain_hello; 2214 struct GNUNET_HELLO_Message *plain_hello;
2163 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pk; 2215 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pk;
2164 struct GNUNET_PeerIdentity target; 2216 struct GNUNET_PeerIdentity target;
2165 struct NeighborList *n; 2217 struct NeighbourList *n;
2166 2218
2167 if (peer == NULL) 2219 if (peer == NULL)
2168 { 2220 {
@@ -2200,7 +2252,7 @@ check_hello_validated (void *cls,
2200 if (h == NULL) 2252 if (h == NULL)
2201 return; 2253 return;
2202 chvc->hello_known = GNUNET_YES; 2254 chvc->hello_known = GNUNET_YES;
2203 n = find_neighbor (peer); 2255 n = find_neighbour (peer);
2204 if (n != NULL) 2256 if (n != NULL)
2205 GNUNET_HELLO_iterate_addresses (h, 2257 GNUNET_HELLO_iterate_addresses (h,
2206 GNUNET_NO, 2258 GNUNET_NO,
@@ -2280,24 +2332,24 @@ process_hello (struct TransportPlugin *plugin,
2280 2332
2281 2333
2282/** 2334/**
2283 * The peer specified by the given neighbor has timed-out or a plugin 2335 * The peer specified by the given neighbour has timed-out or a plugin
2284 * has disconnected. We may either need to do nothing (other plugins 2336 * has disconnected. We may either need to do nothing (other plugins
2285 * still up), or trigger a full disconnect and clean up. This 2337 * still up), or trigger a full disconnect and clean up. This
2286 * function updates our state and does the necessary notifications. 2338 * function updates our state and does the necessary notifications.
2287 * Also notifies our clients that the neighbor is now officially 2339 * Also notifies our clients that the neighbour is now officially
2288 * gone. 2340 * gone.
2289 * 2341 *
2290 * @param n the neighbor list entry for the peer 2342 * @param n the neighbour list entry for the peer
2291 * @param check should we just check if all plugins 2343 * @param check should we just check if all plugins
2292 * disconnected or must we ask all plugins to 2344 * disconnected or must we ask all plugins to
2293 * disconnect? 2345 * disconnect?
2294 */ 2346 */
2295static void 2347static void
2296disconnect_neighbor (struct NeighborList *n, int check) 2348disconnect_neighbour (struct NeighbourList *n, int check)
2297{ 2349{
2298 struct ReadyList *rpos; 2350 struct ReadyList *rpos;
2299 struct NeighborList *npos; 2351 struct NeighbourList *npos;
2300 struct NeighborList *nprev; 2352 struct NeighbourList *nprev;
2301 struct MessageQueue *mq; 2353 struct MessageQueue *mq;
2302 struct ForeignAddressList *peer_addresses; 2354 struct ForeignAddressList *peer_addresses;
2303 struct ForeignAddressList *peer_pos; 2355 struct ForeignAddressList *peer_pos;
@@ -2322,9 +2374,9 @@ disconnect_neighbor (struct NeighborList *n, int check)
2322 "Disconnecting from `%4s'\n", 2374 "Disconnecting from `%4s'\n",
2323 GNUNET_i2s (&n->id)); 2375 GNUNET_i2s (&n->id));
2324#endif 2376#endif
2325 /* remove n from neighbors list */ 2377 /* remove n from neighbours list */
2326 nprev = NULL; 2378 nprev = NULL;
2327 npos = neighbors; 2379 npos = neighbours;
2328 while ((npos != NULL) && (npos != n)) 2380 while ((npos != NULL) && (npos != n))
2329 { 2381 {
2330 nprev = npos; 2382 nprev = npos;
@@ -2332,7 +2384,7 @@ disconnect_neighbor (struct NeighborList *n, int check)
2332 } 2384 }
2333 GNUNET_assert (npos != NULL); 2385 GNUNET_assert (npos != NULL);
2334 if (nprev == NULL) 2386 if (nprev == NULL)
2335 neighbors = n->next; 2387 neighbours = n->next;
2336 else 2388 else
2337 nprev->next = n->next; 2389 nprev->next = n->next;
2338 2390
@@ -2361,7 +2413,7 @@ disconnect_neighbor (struct NeighborList *n, int check)
2361 GNUNET_CONTAINER_DLL_remove (n->messages_head, 2413 GNUNET_CONTAINER_DLL_remove (n->messages_head,
2362 n->messages_tail, 2414 n->messages_tail,
2363 mq); 2415 mq);
2364 GNUNET_assert (0 == memcmp(&mq->neighbor_id, 2416 GNUNET_assert (0 == memcmp(&mq->neighbour_id,
2365 &n->id, 2417 &n->id,
2366 sizeof(struct GNUNET_PeerIdentity))); 2418 sizeof(struct GNUNET_PeerIdentity)));
2367 GNUNET_free (mq); 2419 GNUNET_free (mq);
@@ -2371,6 +2423,11 @@ disconnect_neighbor (struct NeighborList *n, int check)
2371 GNUNET_SCHEDULER_cancel (sched, n->timeout_task); 2423 GNUNET_SCHEDULER_cancel (sched, n->timeout_task);
2372 n->timeout_task = GNUNET_SCHEDULER_NO_TASK; 2424 n->timeout_task = GNUNET_SCHEDULER_NO_TASK;
2373 } 2425 }
2426 if (n->retry_task != GNUNET_SCHEDULER_NO_TASK)
2427 {
2428 GNUNET_SCHEDULER_cancel (sched, n->retry_task);
2429 n->retry_task = GNUNET_SCHEDULER_NO_TASK;
2430 }
2374 /* finally, free n itself */ 2431 /* finally, free n itself */
2375 GNUNET_free (n); 2432 GNUNET_free (n);
2376} 2433}
@@ -2394,7 +2451,7 @@ handle_ping(void *cls, const struct GNUNET_MessageHeader *message,
2394 struct TransportPingMessage *ping; 2451 struct TransportPingMessage *ping;
2395 struct TransportPongMessage *pong; 2452 struct TransportPongMessage *pong;
2396 uint16_t msize; 2453 uint16_t msize;
2397 struct NeighborList *n; 2454 struct NeighbourList *n;
2398 struct ReadyList *rl; 2455 struct ReadyList *rl;
2399 struct ForeignAddressList *fal; 2456 struct ForeignAddressList *fal;
2400 2457
@@ -2440,9 +2497,9 @@ handle_ping(void *cls, const struct GNUNET_MessageHeader *message,
2440 GNUNET_CRYPTO_rsa_sign (my_private_key, 2497 GNUNET_CRYPTO_rsa_sign (my_private_key,
2441 &pong->purpose, &pong->signature)); 2498 &pong->purpose, &pong->signature));
2442 2499
2443 n = find_neighbor(peer); 2500 n = find_neighbour(peer);
2444 if (n == NULL) 2501 if (n == NULL)
2445 n = setup_new_neighbor(peer); 2502 n = setup_new_neighbour(peer);
2446 /* broadcast 'PONG' to all available addresses */ 2503 /* broadcast 'PONG' to all available addresses */
2447 rl = n->plugins; 2504 rl = n->plugins;
2448 while (rl != NULL) 2505 while (rl != NULL)
@@ -2452,6 +2509,7 @@ handle_ping(void *cls, const struct GNUNET_MessageHeader *message,
2452 { 2509 {
2453 transmit_to_peer(NULL, fal, 2510 transmit_to_peer(NULL, fal,
2454 TRANSPORT_PONG_PRIORITY, 2511 TRANSPORT_PONG_PRIORITY,
2512 HELLO_VERIFICATION_TIMEOUT,
2455 (const char *)pong, 2513 (const char *)pong,
2456 ntohs(pong->header.size), 2514 ntohs(pong->header.size),
2457 GNUNET_YES, 2515 GNUNET_YES,
@@ -2495,14 +2553,14 @@ plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
2495 struct InboundMessage *im; 2553 struct InboundMessage *im;
2496 struct ForeignAddressList *peer_address; 2554 struct ForeignAddressList *peer_address;
2497 uint16_t msize; 2555 uint16_t msize;
2498 struct NeighborList *n; 2556 struct NeighbourList *n;
2499 2557
2500 n = find_neighbor (peer); 2558 n = find_neighbour (peer);
2501 if (n == NULL) 2559 if (n == NULL)
2502 { 2560 {
2503 if (message == NULL) 2561 if (message == NULL)
2504 return; /* disconnect of peer already marked down */ 2562 return; /* disconnect of peer already marked down */
2505 n = setup_new_neighbor (peer); 2563 n = setup_new_neighbour (peer);
2506 } 2564 }
2507 service_context = n->plugins; 2565 service_context = n->plugins;
2508 while ((service_context != NULL) && (plugin != service_context->plugin)) 2566 while ((service_context != NULL) && (plugin != service_context->plugin))
@@ -2516,7 +2574,7 @@ plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
2516 GNUNET_i2s (&n->id)); 2574 GNUNET_i2s (&n->id));
2517#endif 2575#endif
2518 /* TODO: call stats */ 2576 /* TODO: call stats */
2519 disconnect_neighbor (n, GNUNET_YES); 2577 disconnect_neighbour (n, GNUNET_YES);
2520 return; 2578 return;
2521 } 2579 }
2522 peer_address = add_peer_address(n, 2580 peer_address = add_peer_address(n,
@@ -2548,7 +2606,7 @@ plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
2548 n->timeout_task = 2606 n->timeout_task =
2549 GNUNET_SCHEDULER_add_delayed (sched, 2607 GNUNET_SCHEDULER_add_delayed (sched,
2550 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 2608 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
2551 &neighbor_timeout_task, n); 2609 &neighbour_timeout_task, n);
2552 update_quota (n); 2610 update_quota (n);
2553 if (n->quota_violation_count > QUOTA_VIOLATION_DROP_THRESHOLD) 2611 if (n->quota_violation_count > QUOTA_VIOLATION_DROP_THRESHOLD)
2554 { 2612 {
@@ -2575,6 +2633,11 @@ plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
2575 if (! n->received_pong) 2633 if (! n->received_pong)
2576 { 2634 {
2577 GNUNET_break_op (0); 2635 GNUNET_break_op (0);
2636#if DEBUG_TRANSPORT || 1
2637 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2638 "Received message of type %u from `%4s', prior to key confirmation (dropped).\n",
2639 ntohs (message->type), GNUNET_i2s (peer));
2640#endif
2578 break; 2641 break;
2579 } 2642 }
2580#if DEBUG_TRANSPORT 2643#if DEBUG_TRANSPORT
@@ -2616,7 +2679,7 @@ handle_start (void *cls,
2616{ 2679{
2617 struct TransportClient *c; 2680 struct TransportClient *c;
2618 struct ConnectInfoMessage cim; 2681 struct ConnectInfoMessage cim;
2619 struct NeighborList *n; 2682 struct NeighbourList *n;
2620 2683
2621#if DEBUG_TRANSPORT 2684#if DEBUG_TRANSPORT
2622 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2685 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2650,7 +2713,7 @@ handle_start (void *cls,
2650 /* tell new client about all existing connections */ 2713 /* tell new client about all existing connections */
2651 cim.header.size = htons (sizeof (struct ConnectInfoMessage)); 2714 cim.header.size = htons (sizeof (struct ConnectInfoMessage));
2652 cim.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT); 2715 cim.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT);
2653 n = neighbors; 2716 n = neighbours;
2654 while (n != NULL) 2717 while (n != NULL)
2655 { 2718 {
2656 if (GNUNET_YES == n->received_pong) 2719 if (GNUNET_YES == n->received_pong)
@@ -2703,7 +2766,7 @@ handle_send (void *cls,
2703 const struct GNUNET_MessageHeader *message) 2766 const struct GNUNET_MessageHeader *message)
2704{ 2767{
2705 struct TransportClient *tc; 2768 struct TransportClient *tc;
2706 struct NeighborList *n; 2769 struct NeighbourList *n;
2707 const struct OutboundMessage *obm; 2770 const struct OutboundMessage *obm;
2708 const struct GNUNET_MessageHeader *obmm; 2771 const struct GNUNET_MessageHeader *obmm;
2709 uint16_t size; 2772 uint16_t size;
@@ -2731,9 +2794,9 @@ handle_send (void *cls,
2731 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 2794 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
2732 return; 2795 return;
2733 } 2796 }
2734 n = find_neighbor (&obm->peer); 2797 n = find_neighbour (&obm->peer);
2735 if (n == NULL) 2798 if (n == NULL)
2736 n = setup_new_neighbor (&obm->peer); 2799 n = setup_new_neighbour (&obm->peer);
2737 tc = clients; 2800 tc = clients;
2738 while ((tc != NULL) && (tc->client != client)) 2801 while ((tc != NULL) && (tc->client != client))
2739 tc = tc->next; 2802 tc = tc->next;
@@ -2744,7 +2807,9 @@ handle_send (void *cls,
2744 ntohs (obmm->size), 2807 ntohs (obmm->size),
2745 ntohs (obmm->type), GNUNET_i2s (&obm->peer)); 2808 ntohs (obmm->type), GNUNET_i2s (&obm->peer));
2746#endif 2809#endif
2747 transmit_to_peer (tc, NULL, ntohl (obm->priority), (char *)obmm, 2810 transmit_to_peer (tc, NULL, ntohl (obm->priority),
2811 GNUNET_TIME_relative_ntoh (obm->timeout),
2812 (char *)obmm,
2748 ntohs (obmm->size), GNUNET_NO, n); 2813 ntohs (obmm->size), GNUNET_NO, n);
2749 GNUNET_SERVER_receive_done (client, GNUNET_OK); 2814 GNUNET_SERVER_receive_done (client, GNUNET_OK);
2750} 2815}
@@ -2764,11 +2829,11 @@ handle_set_quota (void *cls,
2764{ 2829{
2765 const struct QuotaSetMessage *qsm = 2830 const struct QuotaSetMessage *qsm =
2766 (const struct QuotaSetMessage *) message; 2831 (const struct QuotaSetMessage *) message;
2767 struct NeighborList *n; 2832 struct NeighbourList *n;
2768 struct TransportPlugin *p; 2833 struct TransportPlugin *p;
2769 struct ReadyList *rl; 2834 struct ReadyList *rl;
2770 2835
2771 n = find_neighbor (&qsm->peer); 2836 n = find_neighbour (&qsm->peer);
2772 if (n == NULL) 2837 if (n == NULL)
2773 { 2838 {
2774 GNUNET_SERVER_receive_done (client, GNUNET_OK); 2839 GNUNET_SERVER_receive_done (client, GNUNET_OK);
diff --git a/src/transport/transport.h b/src/transport/transport.h
index a336cd9b0..93d36eca9 100644
--- a/src/transport/transport.h
+++ b/src/transport/transport.h
@@ -30,7 +30,7 @@
30#include "gnunet_time_lib.h" 30#include "gnunet_time_lib.h"
31#include "gnunet_transport_service.h" 31#include "gnunet_transport_service.h"
32 32
33#define DEBUG_TRANSPORT GNUNET_YES 33#define DEBUG_TRANSPORT GNUNET_NO
34 34
35/** 35/**
36 * For how long do we allow unused bandwidth 36 * For how long do we allow unused bandwidth
@@ -212,6 +212,11 @@ struct OutboundMessage
212 uint32_t priority GNUNET_PACKED; 212 uint32_t priority GNUNET_PACKED;
213 213
214 /** 214 /**
215 * Allowed delay.
216 */
217 struct GNUNET_TIME_RelativeNBO timeout;
218
219 /**
215 * Which peer should receive the message? 220 * Which peer should receive the message?
216 */ 221 */
217 struct GNUNET_PeerIdentity peer; 222 struct GNUNET_PeerIdentity peer;
diff --git a/src/transport/transport_api.c b/src/transport/transport_api.c
index 84de9cebe..95e7a23fb 100644
--- a/src/transport/transport_api.c
+++ b/src/transport/transport_api.c
@@ -503,6 +503,8 @@ schedule_peer_transmission (struct GNUNET_TRANSPORT_Handle *h)
503 available = n->last_sent + th->notify_size - available; 503 available = n->last_sent + th->notify_size - available;
504 duration = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 504 duration = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
505 available / n->quota_out); 505 available / n->quota_out);
506 if (duration.value == 0)
507 duration = GNUNET_TIME_UNIT_MILLISECONDS;
506 if (th->timeout.value < 508 if (th->timeout.value <
507 GNUNET_TIME_relative_to_absolute (duration).value) 509 GNUNET_TIME_relative_to_absolute (duration).value)
508 { 510 {
@@ -632,6 +634,7 @@ transport_notify_ready (void *cls, size_t size, void *buf)
632 obm.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SEND); 634 obm.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SEND);
633 obm.header.size = htons (mret + sizeof (struct OutboundMessage)); 635 obm.header.size = htons (mret + sizeof (struct OutboundMessage));
634 obm.priority = htonl (th->priority); 636 obm.priority = htonl (th->priority);
637 obm.timeout = GNUNET_TIME_relative_hton (GNUNET_TIME_absolute_get_remaining (th->timeout));
635 obm.peer = n->id; 638 obm.peer = n->id;
636 memcpy (&cbuf[ret], &obm, sizeof (struct OutboundMessage)); 639 memcpy (&cbuf[ret], &obm, sizeof (struct OutboundMessage));
637 ret += (mret + sizeof (struct OutboundMessage)); 640 ret += (mret + sizeof (struct OutboundMessage));