aboutsummaryrefslogtreecommitdiff
path: root/src/core
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/core
parent37971663cf6b082c4d754c711310ba3ac1685b14 (diff)
downloadgnunet-f620d1eee9cb74eed3d87676a61893a906c5ae79.tar.gz
gnunet-f620d1eee9cb74eed3d87676a61893a906c5ae79.zip
fixes
Diffstat (limited to 'src/core')
-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
3 files changed, 229 insertions, 209 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