aboutsummaryrefslogtreecommitdiff
path: root/src/rps
diff options
context:
space:
mode:
authorJulius Bünger <buenger@mytum.de>2015-06-11 23:25:54 +0000
committerJulius Bünger <buenger@mytum.de>2015-06-11 23:25:54 +0000
commitbae032b55dc950aa6a2855104515c13b98fbb020 (patch)
tree659b85e500f44d5b03e85fa76bdd61956ec61b5e /src/rps
parente67bda650f6b6e4a34f70e7095b09b24bda2f6f7 (diff)
downloadgnunet-bae032b55dc950aa6a2855104515c13b98fbb020.tar.gz
gnunet-bae032b55dc950aa6a2855104515c13b98fbb020.zip
-renamed (gossip_list -> view) and converted it to peermap, fixes
Diffstat (limited to 'src/rps')
-rw-r--r--src/rps/gnunet-service-rps.c503
1 files changed, 303 insertions, 200 deletions
diff --git a/src/rps/gnunet-service-rps.c b/src/rps/gnunet-service-rps.c
index 7827919d5..03325da31 100644
--- a/src/rps/gnunet-service-rps.c
+++ b/src/rps/gnunet-service-rps.c
@@ -217,20 +217,22 @@ static struct GNUNET_CONTAINER_MultiPeerMap *peer_map;
217 217
218 218
219/** 219/**
220 * The gossiped list of peers. 220 * Name to log view to
221 */ 221 */
222static struct GNUNET_PeerIdentity *gossip_list; 222static char *file_name_view_log;
223 223
224/** 224/**
225 * Size of the gossiped list 225 * The "local view" containing peers we learned from gossip and history
226 */ 226 */
227//static unsigned int gossip_list_size; 227static struct GNUNET_CONTAINER_MultiPeerMap *view;
228static uint32_t gossip_list_size;
229 228
230/** 229/**
231 * Name to log view (gossip_list) to 230 * An array containing the peers of the local view.
231 *
232 * This is created every time we send a pull reply if it has changed since the
233 * last pull reply we sent.
232 */ 234 */
233static char *file_name_view_log; 235static struct GNUNET_PeerIdentity *view_array;
234 236
235 237
236/** 238/**
@@ -243,9 +245,6 @@ static unsigned int sampler_size_client_need;
243 * The size of sampler we need to be able to satisfy the Brahms protocol's 245 * The size of sampler we need to be able to satisfy the Brahms protocol's
244 * need of random peers. 246 * need of random peers.
245 * 247 *
246 * This is directly taken as the #gossip_list_size on update of the
247 * #gossip_list
248 *
249 * This is one minimum size the sampler grows to. 248 * This is one minimum size the sampler grows to.
250 */ 249 */
251static unsigned int sampler_size_est_need; 250static unsigned int sampler_size_est_need;
@@ -694,11 +693,28 @@ get_peer_ctx (struct GNUNET_CONTAINER_MultiPeerMap *peer_map,
694 void 693 void
695hist_update (void *cls, struct GNUNET_PeerIdentity *ids, uint32_t num_peers) 694hist_update (void *cls, struct GNUNET_PeerIdentity *ids, uint32_t num_peers)
696{ 695{
697 GNUNET_assert (1 == num_peers); 696 unsigned int i;
698 697
699 if (gossip_list_size < sampler_size_est_need) 698 for (i = 0; i < GNUNET_MIN (
699 sampler_size_est_need - GNUNET_CONTAINER_multipeermap_size (view),
700 num_peers); i++)
700 { 701 {
701 GNUNET_array_append (gossip_list, gossip_list_size, *ids); 702 if (GNUNET_OK != GNUNET_CONTAINER_multipeermap_put (view,
703 &ids[i],
704 NULL,
705 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
706 {
707 LOG (GNUNET_ERROR_TYPE_WARNING,
708 "Failed to put peer in peermap. (hist_update)\n");
709 }
710
711 /* Might want to check that we really updated the view */
712 if (NULL != view_array)
713 {
714 GNUNET_free (view_array);
715 view_array = NULL;
716 }
717
702 to_file (file_name_view_log, 718 to_file (file_name_view_log,
703 "+%s\t(hist)", 719 "+%s\t(hist)",
704 GNUNET_i2s_full (ids)); 720 GNUNET_i2s_full (ids));
@@ -867,6 +883,10 @@ check_peer_live (struct PeerContext *peer_ctx)
867 sizeof (struct GNUNET_MessageHeader), 883 sizeof (struct GNUNET_MessageHeader),
868 cadet_ntfy_tmt_rdy_cb, 884 cadet_ntfy_tmt_rdy_cb,
869 peer_ctx); 885 peer_ctx);
886 (void) GNUNET_CONTAINER_multipeermap_put (peer_map,
887 &peer_ctx->peer_id,
888 peer_ctx,
889 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
870 } 890 }
871 else 891 else
872 { 892 {
@@ -934,34 +954,42 @@ insert_in_pull_list_scheduled (const struct PeerContext *peer_ctx)
934 954
935 955
936/** 956/**
937 * Insert PeerID in #gossip_list 957 * Insert PeerID in #view
938 * 958 *
939 * Called once we know a peer is live. 959 * Called once we know a peer is live.
940 */ 960 */
941 void 961 void
942insert_in_gossip_list (void *cls, const struct GNUNET_PeerIdentity *peer) 962insert_in_view (void *cls, const struct GNUNET_PeerIdentity *peer)
943{ 963{
944 if (GNUNET_NO == in_arr (gossip_list, gossip_list_size, peer)) 964 if (GNUNET_YES != GNUNET_CONTAINER_multipeermap_put (view,
965 peer,
966 NULL,
967 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
945 { 968 {
946 GNUNET_array_append (gossip_list, gossip_list_size, *peer); 969 LOG (GNUNET_ERROR_TYPE_WARNING,
947 to_file (file_name_view_log, 970 "Failed to put peer into view. (insert_in_view)\n");
948 "+%s\t(ins in gossip list)", 971 }
949 GNUNET_i2s_full (peer)); 972
973 /* Might want to check whether we really modified the view */
974 if (NULL != view_array)
975 {
976 GNUNET_free (view_array);
977 view_array = NULL;
950 } 978 }
951 979
952 (void) get_channel (peer_map, peer); 980 (void) get_channel (peer_map, peer);
953} 981}
954 982
955/** 983/**
956 * Check whether #insert_in_gossip_list was already scheduled 984 * Check whether #insert_in_view was already scheduled
957 */ 985 */
958 int 986 int
959insert_in_gossip_list_scheduled (const struct PeerContext *peer_ctx) 987insert_in_view_scheduled (const struct PeerContext *peer_ctx)
960{ 988{
961 unsigned int i; 989 unsigned int i;
962 990
963 for ( i = 0 ; i < peer_ctx->num_outstanding_ops ; i++ ) 991 for ( i = 0 ; i < peer_ctx->num_outstanding_ops ; i++ )
964 if (insert_in_gossip_list == peer_ctx->outstanding_ops[i].op) 992 if (insert_in_view == peer_ctx->outstanding_ops[i].op)
965 return GNUNET_YES; 993 return GNUNET_YES;
966 return GNUNET_NO; 994 return GNUNET_NO;
967} 995}
@@ -1108,7 +1136,7 @@ add_peer_array_to_set (const struct GNUNET_PeerIdentity *peer_array,
1108 return; 1136 return;
1109 } 1137 }
1110 1138
1111 for (i = 0 ; i < num_peers ; i++) 1139 for (i = 0; i < num_peers; i++)
1112 { 1140 {
1113 GNUNET_CONTAINER_multipeermap_put (peer_map, 1141 GNUNET_CONTAINER_multipeermap_put (peer_map,
1114 &peer_array[i], 1142 &peer_array[i],
@@ -1180,14 +1208,14 @@ new_peer_id (const struct GNUNET_PeerIdentity *peer_id)
1180 struct PeerOutstandingOp out_op; 1208 struct PeerOutstandingOp out_op;
1181 struct PeerContext *peer_ctx; 1209 struct PeerContext *peer_ctx;
1182 1210
1183 if (NULL != peer_id 1211 if (NULL != peer_id &&
1184 && 0 != GNUNET_CRYPTO_cmp_peer_identity (&own_identity, peer_id)) 1212 0 != GNUNET_CRYPTO_cmp_peer_identity (&own_identity, peer_id))
1185 { 1213 {
1186 LOG (GNUNET_ERROR_TYPE_DEBUG, 1214 LOG (GNUNET_ERROR_TYPE_DEBUG,
1187 "Got peer_id %s (at %p, gossip_list_size: %u)\n", 1215 "Got peer_id %s (at %p, view size: %u)\n",
1188 GNUNET_i2s (peer_id), 1216 GNUNET_i2s (peer_id),
1189 peer_id, 1217 peer_id,
1190 gossip_list_size); 1218 GNUNET_CONTAINER_multipeermap_size (view));
1191 1219
1192 peer_ctx = get_peer_ctx (peer_map, peer_id); 1220 peer_ctx = get_peer_ctx (peer_map, peer_id);
1193 if (GNUNET_YES != get_peer_flag (peer_ctx, VALID)) 1221 if (GNUNET_YES != get_peer_flag (peer_ctx, VALID))
@@ -1201,9 +1229,9 @@ new_peer_id (const struct GNUNET_PeerIdentity *peer_id)
1201 out_op); 1229 out_op);
1202 } 1230 }
1203 1231
1204 if (GNUNET_NO == insert_in_gossip_list_scheduled (peer_ctx)) 1232 if (GNUNET_NO == insert_in_view_scheduled (peer_ctx))
1205 { 1233 {
1206 out_op.op = insert_in_gossip_list; 1234 out_op.op = insert_in_view;
1207 out_op.op_cls = NULL; 1235 out_op.op_cls = NULL;
1208 GNUNET_array_append (peer_ctx->outstanding_ops, 1236 GNUNET_array_append (peer_ctx->outstanding_ops,
1209 peer_ctx->num_outstanding_ops, 1237 peer_ctx->num_outstanding_ops,
@@ -1492,6 +1520,58 @@ handle_peer_push (void *cls,
1492 1520
1493 1521
1494/** 1522/**
1523 * Iterator over hash map entries.
1524 * Called from #generate_view_array and writes every peer id into #view_array.
1525 *
1526 * @param cls closure - the pointer to the counter
1527 * @param key current public key
1528 * @param value value in the hash map
1529 * @return #GNUNET_YES if we should continue to
1530 * iterate,
1531 * #GNUNET_NO if not.
1532 */
1533static int
1534dump_id_to_view_array (void *cls,
1535 const struct GNUNET_PeerIdentity *key,
1536 void *value)
1537{
1538 unsigned int *i = (unsigned int *) cls;
1539
1540 view_array[(*i)++] = *key;
1541 return GNUNET_YES;
1542}
1543
1544
1545/**
1546 * Makes sure the view_array is filled with the peer ids currently in #view.
1547 * Called from within #do_round before sending pushes and pulls and from
1548 * #handle_peer_pull_request when a reply is sent.
1549 */
1550static void
1551generate_view_array (unsigned int view_size)
1552{
1553 unsigned int *i;
1554 int ret;
1555
1556 if (NULL == view_array)
1557 {
1558 view_array = GNUNET_new_array (view_size,
1559 struct GNUNET_PeerIdentity);
1560 i = GNUNET_new (unsigned int);
1561 *i = 0;
1562
1563 ret = GNUNET_CONTAINER_multipeermap_iterate (view,
1564 dump_id_to_view_array,
1565 i);
1566 GNUNET_assert (view_size == ret);
1567 GNUNET_assert (view_size == *i);
1568
1569 GNUNET_free (i);
1570 }
1571}
1572
1573
1574/**
1495 * Handle PULL REQUEST request message from another peer. 1575 * Handle PULL REQUEST request message from another peer.
1496 * 1576 *
1497 * Reply with the gossip list of PeerIDs. 1577 * Reply with the gossip list of PeerIDs.
@@ -1508,6 +1588,7 @@ handle_peer_pull_request (void *cls,
1508 const struct GNUNET_MessageHeader *msg) 1588 const struct GNUNET_MessageHeader *msg)
1509{ 1589{
1510 struct GNUNET_PeerIdentity *peer; 1590 struct GNUNET_PeerIdentity *peer;
1591 unsigned int view_size;
1511 1592
1512 peer = (struct GNUNET_PeerIdentity *) 1593 peer = (struct GNUNET_PeerIdentity *)
1513 GNUNET_CADET_channel_get_info (channel, 1594 GNUNET_CADET_channel_get_info (channel,
@@ -1532,7 +1613,10 @@ handle_peer_pull_request (void *cls,
1532 } 1613 }
1533 #endif /* ENABLE_MALICIOUS */ 1614 #endif /* ENABLE_MALICIOUS */
1534 1615
1535 send_pull_reply (peer, gossip_list, gossip_list_size); 1616 view_size = GNUNET_CONTAINER_multipeermap_size (view);
1617 generate_view_array (view_size);
1618
1619 send_pull_reply (peer, view_array, view_size);
1536 1620
1537 return GNUNET_OK; 1621 return GNUNET_OK;
1538} 1622}
@@ -1993,7 +2077,7 @@ do_mal_round (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1993 2077
1994 2078
1995/** 2079/**
1996 * Send out PUSHes and PULLs, possibly update #gossip_list, samplers. 2080 * Send out PUSHes and PULLs, possibly update #view, samplers.
1997 * 2081 *
1998 * This is executed regylary. 2082 * This is executed regylary.
1999 */ 2083 */
@@ -2003,140 +2087,161 @@ do_round (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2003 LOG (GNUNET_ERROR_TYPE_DEBUG, "Going to execute next round.\n"); 2087 LOG (GNUNET_ERROR_TYPE_DEBUG, "Going to execute next round.\n");
2004 2088
2005 uint32_t i; 2089 uint32_t i;
2090 unsigned int view_size;
2006 unsigned int *permut; 2091 unsigned int *permut;
2007 unsigned int n_peers; /* Number of peers we send pushes/pulls to */ 2092 unsigned int a_peers; /* Number of peers we send pushes to */
2093 unsigned int b_peers; /* Number of peers we send pull requests to */
2008 struct GNUNET_PeerIdentity peer; 2094 struct GNUNET_PeerIdentity peer;
2009 struct GNUNET_PeerIdentity *tmp_peer;
2010 2095
2011 LOG (GNUNET_ERROR_TYPE_DEBUG, 2096 LOG (GNUNET_ERROR_TYPE_DEBUG,
2012 "Printing gossip list:\n"); 2097 "Printing gossip list:\n");
2013 to_file (file_name_view_log, 2098 to_file (file_name_view_log,
2014 "___ new round ___"); 2099 "___ new round ___");
2015 for (i = 0 ; i < gossip_list_size ; i++) 2100 view_size = GNUNET_CONTAINER_multipeermap_size (view);
2101 generate_view_array (view_size);
2102 for (i = 0 ; i < view_size ; i++)
2016 { 2103 {
2017 LOG (GNUNET_ERROR_TYPE_DEBUG, 2104 LOG (GNUNET_ERROR_TYPE_DEBUG,
2018 "\t%s\n", GNUNET_i2s (&gossip_list[i])); 2105 "\t%s\n", GNUNET_i2s (&view_array[i]));
2019 to_file (file_name_view_log, 2106 to_file (file_name_view_log,
2020 "=%s\t(do round)", 2107 "=%s\t(do round)",
2021 GNUNET_i2s_full (&gossip_list[i])); 2108 GNUNET_i2s_full (&view_array[i]));
2022 } 2109 }
2023 // TODO log lists, ...
2024 2110
2025 /* Would it make sense to have one shuffeled gossip list and then
2026 * to send PUSHes to first alpha peers, PULL requests to next beta peers and
2027 * use the rest to update sampler?
2028 * in essence get random peers with consumption */
2029 2111
2030 /* Send PUSHes */ 2112 /* Send pushes and pull requests */
2031 if (0 < gossip_list_size) 2113 if (0 < view_size)
2032 { 2114 {
2033 permut = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_STRONG, 2115 permut = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_STRONG,
2034 (unsigned int) gossip_list_size); 2116 (unsigned int) view_size);
2035 n_peers = ceil (alpha * gossip_list_size); 2117
2118 /* generate view_array */
2119
2120 /* Send PUSHes */
2121 a_peers = ceil (alpha * view_size);
2122
2036 LOG (GNUNET_ERROR_TYPE_DEBUG, 2123 LOG (GNUNET_ERROR_TYPE_DEBUG,
2037 "Going to send pushes to %u (ceil (%f * %u)) peers.\n", 2124 "Going to send pushes to %u (ceil (%f * %u)) peers.\n",
2038 n_peers, alpha, gossip_list_size); 2125 a_peers, alpha, view_size);
2039 for (i = 0 ; i < n_peers ; i++) 2126 for (i = 0; i < a_peers; i++)
2040 { 2127 {
2041 peer = gossip_list[permut[i]]; 2128 peer = view_array[permut[i]];
2042 if (0 != GNUNET_CRYPTO_cmp_peer_identity (&own_identity, &peer)) // TODO 2129 if (0 != GNUNET_CRYPTO_cmp_peer_identity (&own_identity, &peer)) // TODO
2043 { // FIXME if this fails schedule/loop this for later 2130 { // FIXME if this fails schedule/loop this for later
2044 send_push (&peer); 2131 send_push (&peer);
2045 } 2132 }
2046 } 2133 }
2047 GNUNET_free (permut);
2048 }
2049
2050 2134
2051 /* Send PULL requests */ 2135 /* Send PULL requests */
2052 //permut = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_STRONG, (unsigned int) sampler_list->size); 2136 b_peers = a_peers + floor (beta * view_size);
2053 n_peers = ceil (beta * gossip_list_size); 2137 LOG (GNUNET_ERROR_TYPE_DEBUG,
2054 LOG (GNUNET_ERROR_TYPE_DEBUG, 2138 "Going to send pulls to %u (ceil (%f * %u)) peers.\n",
2055 "Going to send pulls to %u (ceil (%f * %u)) peers.\n", 2139 b_peers, beta, view_size);
2056 n_peers, beta, gossip_list_size); 2140 for (i = a_peers; i < b_peers; i++)
2057 for (i = 0 ; i < n_peers ; i++)
2058 {
2059 tmp_peer = get_rand_peer_ignore_list (gossip_list, gossip_list_size,
2060 pending_pull_reply_list, pending_pull_reply_list_size);
2061 if (NULL != tmp_peer)
2062 { 2141 {
2063 peer = *tmp_peer; 2142 peer = view_array[permut[i]];
2064 GNUNET_free (tmp_peer); 2143 if (0 != GNUNET_CRYPTO_cmp_peer_identity (&own_identity, &peer) &&
2065 2144 GNUNET_YES != in_arr (pending_pull_reply_list,
2066 if (0 != GNUNET_CRYPTO_cmp_peer_identity (&own_identity, &peer)) 2145 pending_pull_reply_list_size,
2067 { 2146 &peer)) // TODO
2147 { // FIXME if this fails schedule/loop this for later
2068 send_pull_request (&peer); 2148 send_pull_request (&peer);
2069 } 2149 }
2070 } 2150 }
2151
2152 GNUNET_free (permut);
2153 permut = NULL;
2071 } 2154 }
2072 2155
2073 2156
2074 /* Update gossip list */ 2157 /* Update view */
2075 /* TODO see how many peers are in push-/pull- list! */ 2158 /* TODO see how many peers are in push-/pull- list! */
2076 2159
2077 if (push_list_size <= alpha * gossip_list_size 2160 if (push_list_size <= alpha * view_size &&
2078 && push_list_size > 0 2161 0 < push_list_size &&
2079 && pull_list_size > 0) 2162 0 < pull_list_size)
2080 { 2163 {
2081 LOG (GNUNET_ERROR_TYPE_DEBUG, "Update of the gossip list.\n"); 2164 LOG (GNUNET_ERROR_TYPE_DEBUG, "Update of the gossip list.\n");
2082 2165
2083 uint32_t first_border; 2166 uint32_t first_border;
2084 uint32_t second_border; 2167 uint32_t second_border;
2085 uint32_t r_index; 2168 uint32_t final_size;
2086 uint32_t peers_to_clean_size; 2169 uint32_t peers_to_clean_size;
2087 struct GNUNET_PeerIdentity *peers_to_clean; 2170 struct GNUNET_PeerIdentity *peers_to_clean;
2088 2171
2089 peers_to_clean = NULL; 2172 peers_to_clean = NULL;
2090 peers_to_clean_size = 0; 2173 peers_to_clean_size = 0;
2091 GNUNET_array_grow (peers_to_clean, peers_to_clean_size, gossip_list_size); 2174 GNUNET_array_grow (peers_to_clean, peers_to_clean_size, view_size);
2092 memcpy (peers_to_clean, 2175 memcpy (peers_to_clean,
2093 gossip_list, 2176 view_array,
2094 gossip_list_size * sizeof (struct GNUNET_PeerIdentity)); 2177 view_size * sizeof (struct GNUNET_PeerIdentity));
2178
2179 /* Seems like recreating is the easiest way of emptying the peermap */
2180 GNUNET_CONTAINER_multipeermap_destroy (view);
2181 view = GNUNET_CONTAINER_multipeermap_create (view_size, GNUNET_NO);
2095 2182
2096 first_border = ceil (alpha * sampler_size_est_need); 2183 /* first_border = ceil (alpha * sampler_size_est_need);
2097 second_border = first_border + ceil (beta * sampler_size_est_need); 2184 second_border = first_border + ceil (beta * sampler_size_est_need); */
2185 first_border = GNUNET_MIN (ceil (alpha * sampler_size_est_need),
2186 push_list_size);
2187 second_border = first_border +
2188 GNUNET_MIN (floor (beta * sampler_size_est_need),
2189 pull_list_size);
2190 final_size = second_border +
2191 ceil ((1 - (alpha + beta)) * sampler_size_est_need);
2098 2192
2099 GNUNET_array_grow (gossip_list, gossip_list_size, second_border); 2193 GNUNET_array_grow (view_array, view_size, second_border);
2100 2194
2101 to_file (file_name_view_log, 2195 to_file (file_name_view_log,
2102 "--- emptied ---"); 2196 "--- emptied ---");
2103 2197
2104 for (i = 0 ; i < first_border ; i++) 2198 /* Update view with peers received through PUSHes */
2105 {/* Update gossip list with peers received through PUSHes */ 2199 permut = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_STRONG,
2106 r_index = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG, 2200 pull_list_size);
2107 push_list_size); 2201 for (i = 0; i < first_border; i++)
2108 gossip_list[i] = push_list[r_index]; 2202 {
2203 view_array[i] = push_list[permut[i]];
2204 GNUNET_CONTAINER_multipeermap_put (view, &push_list[permut[i]], NULL,
2205 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
2206
2109 to_file (file_name_view_log, 2207 to_file (file_name_view_log,
2110 "+%s't(push list)", 2208 "+%s't(push list)",
2111 GNUNET_i2s_full (&gossip_list[i])); 2209 GNUNET_i2s_full (&view_array[i]));
2112 // TODO change the peer_flags accordingly 2210 // TODO change the peer_flags accordingly
2113 } 2211 }
2212 GNUNET_free (permut);
2213 permut = NULL;
2214
2215 /* Update view with peers received through PULLs */
2216 permut = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_STRONG,
2217 pull_list_size);
2218 for (i = first_border; i < second_border; i++)
2219 {
2220 view_array[i] = pull_list[permut[i]];
2221 GNUNET_CONTAINER_multipeermap_put (view, &pull_list[permut[i]], NULL,
2222 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
2114 2223
2115 for (i = first_border ; i < second_border ; i++)
2116 {/* Update gossip list with peers received through PULLs */
2117 r_index = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_STRONG,
2118 pull_list_size);
2119 gossip_list[i] = pull_list[r_index];
2120 to_file (file_name_view_log, 2224 to_file (file_name_view_log,
2121 "+%s\t(pull list)", 2225 "+%s\t(pull list)",
2122 GNUNET_i2s_full (&gossip_list[i])); 2226 GNUNET_i2s_full (&view_array[i]));
2123 // TODO change the peer_flags accordingly 2227 // TODO change the peer_flags accordingly
2124 } 2228 }
2229 GNUNET_free (permut);
2230 permut = NULL;
2125 2231
2126 for (i = second_border ; i < sampler_size_est_need ; i++) 2232 /* Update view with peers from history */
2127 {/* Update gossip list with peers from history */ 2233 RPS_sampler_get_n_rand_peers (prot_sampler,
2128 RPS_sampler_get_n_rand_peers (prot_sampler, 2234 hist_update,
2129 hist_update, 2235 NULL,
2130 NULL, 2236 final_size - second_border);
2131 1); 2237 num_hist_update_tasks = final_size - second_border;
2132 num_hist_update_tasks++; 2238 // TODO change the peer_flags accordingly
2133 // TODO change the peer_flags accordingly
2134 }
2135 2239
2136 for (i = 0 ; i < gossip_list_size ; i++) 2240 for (i = 0; i < view_size; i++)
2137 rem_from_list (&peers_to_clean, &peers_to_clean_size, &gossip_list[i]); 2241 rem_from_list (&peers_to_clean, &peers_to_clean_size, &view_array[i]);
2138 2242
2139 for (i = 0 ; i < peers_to_clean_size ; i++) 2243 /* Clean peers that were removed from the view */
2244 for (i = 0; i < peers_to_clean_size; i++)
2140 { 2245 {
2141 peer_clean (&peers_to_clean[i]); 2246 peer_clean (&peers_to_clean[i]);
2142 /* to_file (file_name_view_log, 2247 /* to_file (file_name_view_log,
@@ -2145,6 +2250,7 @@ do_round (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2145 } 2250 }
2146 2251
2147 GNUNET_free (peers_to_clean); 2252 GNUNET_free (peers_to_clean);
2253 peers_to_clean = NULL;
2148 } 2254 }
2149 else 2255 else
2150 { 2256 {
@@ -2153,15 +2259,15 @@ do_round (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2153 // TODO independent of that also get some peers from CADET_get_peers()? 2259 // TODO independent of that also get some peers from CADET_get_peers()?
2154 2260
2155 LOG (GNUNET_ERROR_TYPE_DEBUG, 2261 LOG (GNUNET_ERROR_TYPE_DEBUG,
2156 "Received %u pushes and %u pulls last round (alpha (%.2f) * gossip_list_size (%u) = %.2f)\n", 2262 "Received %u pushes and %u pulls last round (alpha (%.2f) * view_size (%u) = %.2f)\n",
2157 push_list_size, 2263 push_list_size,
2158 pull_list_size, 2264 pull_list_size,
2159 alpha, 2265 alpha,
2160 gossip_list_size, 2266 view_size,
2161 alpha * gossip_list_size); 2267 alpha * view_size);
2162 2268
2163 /* Update samplers */ 2269 /* Update samplers */
2164 for ( i = 0 ; i < push_list_size ; i++ ) 2270 for (i = 0; i < push_list_size; i++)
2165 { 2271 {
2166 LOG (GNUNET_ERROR_TYPE_DEBUG, 2272 LOG (GNUNET_ERROR_TYPE_DEBUG,
2167 "Updating with peer %s from push list\n", 2273 "Updating with peer %s from push list\n",
@@ -2171,7 +2277,7 @@ do_round (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2171 // TODO set in_flag? 2277 // TODO set in_flag?
2172 } 2278 }
2173 2279
2174 for ( i = 0 ; i < pull_list_size ; i++ ) 2280 for (i = 0; i < pull_list_size; i++)
2175 { 2281 {
2176 LOG (GNUNET_ERROR_TYPE_DEBUG, 2282 LOG (GNUNET_ERROR_TYPE_DEBUG,
2177 "Updating with peer %s from pull list\n", 2283 "Updating with peer %s from pull list\n",
@@ -2191,7 +2297,6 @@ do_round (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2191 time_next_round = compute_rand_delay (round_interval, 2); 2297 time_next_round = compute_rand_delay (round_interval, 2);
2192 2298
2193 /* Schedule next round */ 2299 /* Schedule next round */
2194 //do_round_task = GNUNET_SCHEDULER_add_delayed (round_interval, &do_round, NULL);
2195 do_round_task = GNUNET_SCHEDULER_add_delayed (time_next_round, &do_round, NULL); 2300 do_round_task = GNUNET_SCHEDULER_add_delayed (time_next_round, &do_round, NULL);
2196 LOG (GNUNET_ERROR_TYPE_DEBUG, "Finished round\n"); 2301 LOG (GNUNET_ERROR_TYPE_DEBUG, "Finished round\n");
2197} 2302}
@@ -2258,8 +2363,8 @@ peer_clean (const struct GNUNET_PeerIdentity *peer)
2258 struct PeerContext *peer_ctx; 2363 struct PeerContext *peer_ctx;
2259 struct GNUNET_CADET_Channel *channel; 2364 struct GNUNET_CADET_Channel *channel;
2260 2365
2261 if (GNUNET_YES != in_arr (gossip_list, gossip_list_size, peer) 2366 if (GNUNET_YES != GNUNET_CONTAINER_multipeermap_contains (view, peer) &&
2262 && GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (peer_map, peer)) 2367 GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (peer_map, peer))
2263 { 2368 {
2264 peer_ctx = get_peer_ctx (peer_map, peer); 2369 peer_ctx = get_peer_ctx (peer_map, peer);
2265 if (NULL != peer_ctx->send_channel) 2370 if (NULL != peer_ctx->send_channel)
@@ -2281,10 +2386,9 @@ peer_remove_cb (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
2281 struct PeerContext *peer_ctx; 2386 struct PeerContext *peer_ctx;
2282 const struct GNUNET_CADET_Channel *channel = 2387 const struct GNUNET_CADET_Channel *channel =
2283 (const struct GNUNET_CADET_Channel *) cls; 2388 (const struct GNUNET_CADET_Channel *) cls;
2284 struct GNUNET_CADET_Channel *recv;
2285 struct GNUNET_CADET_Channel *send;
2286 2389
2287 peer_ctx = (struct PeerContext *) value; 2390 peer_ctx = (struct PeerContext *) value;
2391 set_peer_flag (peer_ctx, TO_DESTROY);
2288 2392
2289 LOG (GNUNET_ERROR_TYPE_DEBUG, 2393 LOG (GNUNET_ERROR_TYPE_DEBUG,
2290 "Going to clean peer %s\n", 2394 "Going to clean peer %s\n",
@@ -2292,29 +2396,31 @@ peer_remove_cb (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
2292 2396
2293 /* If operations are still scheduled for this peer cancel those */ 2397 /* If operations are still scheduled for this peer cancel those */
2294 if (0 != peer_ctx->num_outstanding_ops) 2398 if (0 != peer_ctx->num_outstanding_ops)
2399 {
2295 GNUNET_array_grow (peer_ctx->outstanding_ops, 2400 GNUNET_array_grow (peer_ctx->outstanding_ops,
2296 peer_ctx->num_outstanding_ops, 2401 peer_ctx->num_outstanding_ops,
2297 0); 2402 0);
2403 }
2298 2404
2299 /* If we are still waiting for notification whether this peer is live 2405 /* If we are still waiting for notification whether this peer is live
2300 * cancel the according task */ 2406 * cancel the according task */
2301 if (NULL != peer_ctx->is_live_task) 2407 if (NULL != peer_ctx->is_live_task)
2302 { 2408 {
2303 LOG (GNUNET_ERROR_TYPE_DEBUG, 2409 LOG (GNUNET_ERROR_TYPE_DEBUG,
2304 "Trying to cancle is_live_task for peer %s\n", 2410 "Trying to cancle is_live_task for peer %s\n",
2305 GNUNET_i2s (key)); 2411 GNUNET_i2s (key));
2306 GNUNET_CADET_notify_transmit_ready_cancel (peer_ctx->is_live_task); 2412 GNUNET_CADET_notify_transmit_ready_cancel (peer_ctx->is_live_task);
2307 peer_ctx->is_live_task = NULL; 2413 peer_ctx->is_live_task = NULL;
2308 } 2414 }
2309 2415
2416 rem_from_list (&pending_pull_reply_list,
2417 &pending_pull_reply_list_size,
2418 key);
2310 2419
2311 recv = peer_ctx->recv_channel; 2420 to_file (file_name_view_log,
2312 peer_ctx->recv_channel = NULL; 2421 "-%s\t(cleanup channel, other peer)",
2313 if (NULL != recv 2422 GNUNET_i2s_full (key));
2314 && channel != recv) 2423 GNUNET_CONTAINER_multipeermap_remove_all (view, key);
2315 {
2316 GNUNET_CADET_channel_destroy (recv);
2317 }
2318 2424
2319 /* If there is still a mq destroy it */ 2425 /* If there is still a mq destroy it */
2320 if (NULL != peer_ctx->mq) 2426 if (NULL != peer_ctx->mq)
@@ -2323,25 +2429,33 @@ peer_remove_cb (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
2323 peer_ctx->mq = NULL; 2429 peer_ctx->mq = NULL;
2324 } 2430 }
2325 2431
2432
2326 /* Remove the send_channel 2433 /* Remove the send_channel
2327 * The peer map entry should be removed 2434 * This function should be called again from #cleanup_channel (callback
2328 * from the callback #cleanup_channel */ 2435 * called on the destruction of channels) and clean up the rest. */
2329 send = peer_ctx->send_channel; 2436 if (NULL != peer_ctx->send_channel &&
2330 peer_ctx->send_channel = NULL; 2437 channel != peer_ctx->send_channel)
2331 if (NULL != send
2332 && channel != send)
2333 { 2438 {
2334 set_peer_flag (peer_ctx, TO_DESTROY); 2439 GNUNET_CADET_channel_destroy (peer_ctx->send_channel);
2335 GNUNET_CADET_channel_destroy (send); 2440 peer_ctx->send_channel = NULL;
2336 } 2441 }
2337 else 2442
2338 { /* If there is no channel we have to remove it now */ 2443 /* Remove the recv_channel
2339 if (GNUNET_YES != GNUNET_CONTAINER_multipeermap_remove_all (peer_map, key)) 2444 * This function should be called again from #cleanup_channel (callback
2340 LOG (GNUNET_ERROR_TYPE_WARNING, "removing peer from peer_map failed\n"); 2445 * called on the destruction of channels) and clean up the rest. */
2341 else 2446 if (NULL != peer_ctx->recv_channel &&
2342 GNUNET_free (peer_ctx); 2447 channel != peer_ctx->recv_channel)
2448 {
2449 GNUNET_CADET_channel_destroy (peer_ctx->recv_channel);
2450 peer_ctx->recv_channel = NULL;
2343 } 2451 }
2344 2452
2453 /* If there is no channel we have to remove the context now */
2454 if (GNUNET_YES != GNUNET_CONTAINER_multipeermap_remove_all (peer_map, key))
2455 LOG (GNUNET_ERROR_TYPE_WARNING, "removing peer from peer_map failed\n");
2456
2457 GNUNET_free (peer_ctx);
2458
2345 return GNUNET_YES; 2459 return GNUNET_YES;
2346} 2460}
2347 2461
@@ -2381,10 +2495,11 @@ shutdown_task (void *cls,
2381 LOG (GNUNET_ERROR_TYPE_DEBUG, 2495 LOG (GNUNET_ERROR_TYPE_DEBUG,
2382 "Size of the peermap: %u\n", 2496 "Size of the peermap: %u\n",
2383 GNUNET_CONTAINER_multipeermap_size (peer_map)); 2497 GNUNET_CONTAINER_multipeermap_size (peer_map));
2384 GNUNET_break (0 == GNUNET_CONTAINER_multipeermap_size (peer_map)); 2498 GNUNET_break (0 != GNUNET_CONTAINER_multipeermap_size (peer_map));
2385 GNUNET_CONTAINER_multipeermap_destroy (peer_map); 2499 GNUNET_CONTAINER_multipeermap_destroy (peer_map);
2386 GNUNET_CADET_disconnect (cadet_handle); 2500 GNUNET_CADET_disconnect (cadet_handle);
2387 GNUNET_array_grow (gossip_list, gossip_list_size, 0); 2501 GNUNET_CONTAINER_multipeermap_destroy (view);
2502 view = NULL;
2388 GNUNET_array_grow (push_list, push_list_size, 0); 2503 GNUNET_array_grow (push_list, push_list_size, 0);
2389 GNUNET_array_grow (pull_list, pull_list_size, 0); 2504 GNUNET_array_grow (pull_list, pull_list_size, 0);
2390 #ifdef ENABLE_MALICIOUS 2505 #ifdef ENABLE_MALICIOUS
@@ -2456,6 +2571,12 @@ handle_inbound_channel (void *cls,
2456 (void) GNUNET_CONTAINER_multipeermap_put (peer_map, &peer, peer_ctx, 2571 (void) GNUNET_CONTAINER_multipeermap_put (peer_map, &peer, peer_ctx,
2457 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); 2572 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
2458 2573
2574 /* This would make the push-message unnecessary */
2575 LOG (GNUNET_ERROR_TYPE_DEBUG,
2576 "Got peer_id %s from peerinfo\n",
2577 GNUNET_i2s (&peer));
2578 new_peer_id (&peer);
2579
2459 peer_is_live (peer_ctx); 2580 peer_is_live (peer_ctx);
2460 2581
2461 return NULL; // TODO 2582 return NULL; // TODO
@@ -2463,7 +2584,7 @@ handle_inbound_channel (void *cls,
2463 2584
2464 2585
2465/** 2586/**
2466 * This is called when a remote peer destroys a channel. 2587 * This is called when a channel is destroyed.
2467 * 2588 *
2468 * @param cls The closure 2589 * @param cls The closure
2469 * @param channel The channel being closed 2590 * @param channel The channel being closed
@@ -2482,75 +2603,58 @@ cleanup_channel (void *cls,
2482 // Guess simply casting isn't the nicest way... 2603 // Guess simply casting isn't the nicest way...
2483 // FIXME wait for cadet to change this function 2604 // FIXME wait for cadet to change this function
2484 2605
2485 //if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (peer_map, peer)) 2606 if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (peer_map, peer))
2486 //{ 2607 {/* We don't want to implicitly create a context that we're about to kill */
2487 peer_ctx = GNUNET_CONTAINER_multipeermap_get (peer_map, peer); 2608 peer_ctx = GNUNET_CONTAINER_multipeermap_get (peer_map, peer);
2488
2489 if (NULL == peer_ctx) /* It could have been removed by shutdown_task */ 2609 if (NULL == peer_ctx) /* It could have been removed by shutdown_task */
2490 return; 2610 return;
2491 2611
2612 if (get_peer_flag (peer_ctx, TO_DESTROY))
2613 {/* We initiatad the destruction of this particular peer */
2614 if (channel == peer_ctx->send_channel)
2615 peer_ctx->send_channel = NULL;
2616 else if (channel == peer_ctx->recv_channel)
2617 peer_ctx->recv_channel = NULL;
2492 2618
2493 if (channel == peer_ctx->send_channel)
2494 { /* Something (but us) killd the channel */
2495 LOG (GNUNET_ERROR_TYPE_DEBUG,
2496 "send channel (%s) was destroyed - cleaning up\n",
2497 GNUNET_i2s (peer));
2498
2499 rem_from_list (&gossip_list,
2500 &gossip_list_size,
2501 peer);
2502 rem_from_list (&pending_pull_reply_list,
2503 &pending_pull_reply_list_size,
2504 peer);
2505 to_file (file_name_view_log,
2506 "-%s\t(cleanup channel, other peer)",
2507 GNUNET_i2s_full (peer));
2508
2509 peer_ctx->send_channel = NULL;
2510 /* Somwewhat {ab,re}use the iterator function */
2511 /* Cast to void is ok, because it's used as void in peer_remove_cb */
2512 (void) peer_remove_cb ((void *) channel, peer, peer_ctx);
2513
2514 //if (GNUNET_YES != GNUNET_CONTAINER_multipeermap_remove_all (peer_map, key))
2515 // LOG (GNUNET_ERROR_TYPE_WARNING, "Removing peer from peer_map failed\n");
2516 //else
2517 // GNUNET_free (peer_ctx);
2518 }
2519 else if (channel == peer_ctx->recv_channel)
2520 { /* Other peer doesn't want to send us messages anymore */
2521 LOG (GNUNET_ERROR_TYPE_DEBUG,
2522 "Peer %s destroyed recv channel - cleaning up channel\n",
2523 GNUNET_i2s (peer));
2524 peer_ctx->recv_channel = NULL;
2525 }
2526 else if (NULL == peer_ctx->send_channel &&
2527 get_peer_flag (peer_ctx, TO_DESTROY))
2528 { /* We closed the channel to that peer */
2529 LOG (GNUNET_ERROR_TYPE_DEBUG,
2530 "send channel (%s) was destroyed by us - cleaning up\n",
2531 GNUNET_i2s (peer));
2532
2533 rem_from_list (&gossip_list,
2534 &gossip_list_size,
2535 peer);
2536 rem_from_list (&pending_pull_reply_list,
2537 &pending_pull_reply_list_size,
2538 peer);
2539 to_file (file_name_view_log, 2619 to_file (file_name_view_log,
2540 "-%s\t(cleanup channel, ourself)", 2620 "-%s\t(cleanup channel, ourself)",
2541 GNUNET_i2s_full (peer)); 2621 GNUNET_i2s_full (peer));
2542
2543 /* Somwewhat {ab,re}use the iterator function */
2544 /* Cast to void is ok, because it's used as void in peer_remove_cb */
2545 (void) peer_remove_cb ((void *) channel, peer, peer_ctx);
2546 } 2622 }
2623
2547 else 2624 else
2548 { 2625 { /* We did not initiate the destruction of this peer */
2549 LOG (GNUNET_ERROR_TYPE_WARNING, 2626 if (channel == peer_ctx->send_channel)
2550 "unknown channel (%s) was destroyed\n", 2627 { /* Something (but us) killd the channel - clean up peer */
2551 GNUNET_i2s (peer)); 2628 LOG (GNUNET_ERROR_TYPE_DEBUG,
2629 "send channel (%s) was destroyed - cleaning up\n",
2630 GNUNET_i2s (peer));
2631 peer_ctx->send_channel = NULL;
2632 /* Somwewhat {ab,re}use the iterator function */
2633 /* Cast to void is ok, because it's used as void in peer_remove_cb */
2634 (void) peer_remove_cb ((void *) channel, peer, peer_ctx);
2635 }
2636 else if (channel == peer_ctx->recv_channel)
2637 { /* Other peer doesn't want to send us messages anymore */
2638 LOG (GNUNET_ERROR_TYPE_DEBUG,
2639 "Peer %s destroyed recv channel - cleaning up channel\n",
2640 GNUNET_i2s (peer));
2641 peer_ctx->recv_channel = NULL;
2642 }
2643 else
2644 {
2645 LOG (GNUNET_ERROR_TYPE_WARNING,
2646 "unknown channel (%s) was destroyed\n",
2647 GNUNET_i2s (peer));
2648 }
2552 } 2649 }
2553 //} 2650 }
2651
2652 else
2653 { /* We don't know a context to that peer */
2654 LOG (GNUNET_ERROR_TYPE_DEBUG,
2655 "channel (%s) without associated context was destroyed\n",
2656 GNUNET_i2s (peer));
2657 }
2554} 2658}
2555 2659
2556 2660
@@ -2641,8 +2745,7 @@ run (void *cls,
2641 LOG (GNUNET_ERROR_TYPE_DEBUG, "INITSIZE is %" PRIu64 "\n", sampler_size_est_need); 2745 LOG (GNUNET_ERROR_TYPE_DEBUG, "INITSIZE is %" PRIu64 "\n", sampler_size_est_need);
2642 2746
2643 2747
2644 gossip_list = NULL; 2748 view = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_NO);
2645 gossip_list_size = 0;
2646 2749
2647 /* file_name_view_log */ 2750 /* file_name_view_log */
2648 if (GNUNET_OK != GNUNET_DISK_directory_create ("/tmp/rps/")) 2751 if (GNUNET_OK != GNUNET_DISK_directory_create ("/tmp/rps/"))