[On W32, we need to select after calling socket before
doing connect etc.]
* TRANSPORT:
- - transport_api: support forcing disconnects through low quotas!
- (required for working F2F support!)
- - API: consider having core provide deadline information for each message
- (likely important for DV plugin which wants to loop back!)
- implement transport API to pretty-print transport address
+ transport_api extension (API extension!)
+ service-transport extension (protocol extension)
+ How necessary is ACKing in the first place? (alternatives?)
+ Should we transmit ACKs in response to every HELLO? (would that
fully address the problem?)
- - latency measurements implemented in the transport
- plugins makes it only work for bi-di transports
- and results in code replication
- - should latency be included in the ReceiveCallback and
- NotifyConnect or passed on request?
- - FIXME's with latency being simply set to 0 in a few places
- [./transport/gnunet-service-transport.c:173]: (style) struct or union member 'TransportPlugin::rebuild' is never used
- [./transport/plugin_transport_tcp.c:391]: (style) struct or union member 'Plugin::address_update_task' is never used
-
* FS:
- [./fs/gnunet-service-fs.c:208]: (style) struct or union member 'LocalGetContext::results_bf_size' is never used
- [./fs/gnunet-service-fs.c:501]: (style) struct or union member 'PendingRequest::used_pids_size' is never used
- [./fs/gnunet-service-fs.c:688]: (style) struct or union member 'ConnectedPeer::pending_requests' is never used
- [./fs/gnunet-service-fs.c:694]: (style) struct or union member 'ConnectedPeer::last_p2p_replies_woff' is never used
- [./fs/gnunet-service-fs.c:700]: (style) struct or union member 'ConnectedPeer::last_client_replies_woff' is never used
-
* TOPOLOGY:
- - [./topology/gnunet-daemon-topology.c:94]: (style) struct or union member 'PeerList::last_hello_sent' is never used
-
+ - If the topology daemon crashes, peers that were put on the
+ blacklist with transport will never be removed from it (until
+ transport service dies); we should use the blacklist notification
+ API to learn about the exact set of blacklisted peers at all times
+ (FIXME: the transport_api implementation of blacklisting
+ also does not work nicely for this since it won't let us know about
+ disconnect-reconnect events and the implicit whitelisting
+ that might happen here; that's not so bad since we will
+ re-blacklist on pre-connect attempts anyway, so this is
+ a minor issue).
+ - the code uses the term 'blacklist' for both peers that are forbidden
+ to connect (i.e. F2F mode) as well as peers that we currently
+ won't try to actively connect to ourselves (since we just tried);
+ This is confusing. We need two distinct terms.
+ - move code to use hash table instead of linked list
+ - instead of periodically discarding blacklisted entries,
+ simply add task that is triggered at the right time (earlier free,
+ more balanced load)
+ - check if new HELLO learned is different from old HELLO
+ before resetting entire state!
* SETUP:
- auto-generate "defaults.conf" using gnunet-setup from "config.scm"
- integrate all options into "config.scm"
- main service not implemented [Nate]
- testcases crash & burn (no surprise)
* CORE:
- - request disconnect not implemented [Christian]
- - various notification options not implemented [Christian]
- outbound message monitoring not supported [Christian]
- test currently fails spectacularly [segv of transport service]
=> need transport to work first!
* TOPOLOGY:
- needs testing [need transport first]
* HOSTLIST:
- - test fails (looks like it works, but that's because of a bad
- connectivity notification; somehow core is unable to send
- messages successfully via transport) [need transport first]
+ - needs testing [need transport first]
* FS (basic anonymous FS only)
- implement FS service (P2P operations)
+ how to send queries (soliciting is not there in core; do we
* @file topology/gnunet-daemon-topology.c
* @brief code for maintaining the mesh topology
* @author Christian Grothoff
- *
- * OPTIMIZATIONS:
- * - move code to use hash table instead of linked list
- * - instead of periodically discarding blacklisted entries,
- * simply add task that is triggered at the right time (earlier free,
- * more balanced load)
- * - check if new HELLO learned is different from old HELLO
- * before resetting entire state!
*/
#include <stdlib.h>
*/
struct GNUNET_CONTAINER_BloomFilter *filter;
+ /**
+ * Our request handle for *whitelisting* this peer (NULL if
+ * no whitelisting request is pending).
+ */
+ struct GNUNET_TRANSPORT_BlacklistRequest *wh;
+
/**
* Is this peer listed here because he is a friend?
*/
*/
int is_connected;
+ /**
+ * Are we currently blocking this peer (via blacklist)?
+ */
+ int is_blocked;
+
/**
* Until what time should we not try to connect again
* to this peer?
/**
* Force a disconnect from the specified peer.
- * FIXME: this policy change is never undone; how do we reconnect ever?
*/
static void
-force_disconnect (const struct GNUNET_PeerIdentity *peer)
+force_disconnect (struct PeerList *pl)
{
+ const struct GNUNET_PeerIdentity *peer = &pl->id;
struct DisconnectList *dl;
+ if (NULL != dl->wh)
+ {
+ GNUNET_TRANSPORT_blacklist_cancel (dl->wh);
+ dl->wh = NULL;
+ }
+ pl->is_blocked = GNUNET_YES;
dl = GNUNET_malloc (sizeof (struct DisconnectList));
dl->peer = *peer;
GNUNET_CONTAINER_DLL_insert (disconnect_head,
}
+
+/**
+ * Function called once our request to 'whitelist' a peer
+ * has completed.
+ *
+ * @param cls our 'struct PeerList'
+ * @param tc unused
+ */
+static void
+whitelist_done (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct PeerList *pl = cls;
+
+ pl->wh = NULL;
+}
+
+
+/**
+ * Whitelist all peers that we blacklisted; we've passed
+ * the minimum number of friends.
+ */
+static void
+whitelist_peers ()
+{
+ struct PeerList *pl;
+ struct DisconnectList *dl;
+
+ /* first, cancel all blacklisting requests */
+ while (NULL != (dl = disconnect_head))
+ {
+ GNUNET_CONTAINER_DLL_remove (disconnect_head,
+ disconnect_tail,
+ dl);
+ GNUNET_TRANSPORT_blacklist_cancel (dl->rh);
+ GNUNET_free (dl);
+ }
+ /* then, specifically whitelist all peers that we
+ know to have blacklisted */
+ pl = peers;
+ while (pl != NULL)
+ {
+ if (pl->is_blocked)
+ {
+ pl->wh = GNUNET_TRANSPORT_blacklist (sched, cfg,
+ peer,
+ GNUNET_TIME_UNIT_FOREVER_ZERO,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ &whitelist_done,
+ pl);
+ pl->is_blocked = GNUNET_NO;
+ }
+ pl = pl->next;
+ }
+}
+
+
/**
* Function called by core when our attempt to connect succeeded.
*/
prev->next = pos->next;
if (pos->hello_req != NULL)
GNUNET_CORE_notify_transmit_ready_cancel (pos->hello_req);
+ if (pos->wh != NULL)
+ GNUNET_TRANSPORT_blacklist_cancel (pos->wh);
if (pos->connect_req != NULL)
GNUNET_CORE_peer_request_connect_cancel (pos->connect_req);
if (pos->hello_delay_task != GNUNET_SCHEDULER_NO_TASK)
"Connection to `%s' is forbidden, forcing disconnect!\n",
GNUNET_i2s (peer));
#endif
- force_disconnect (&pos->id);
+ force_disconnect (pos);
return;
}
}
}
pos->is_connected = GNUNET_YES;
if (pos->is_friend)
- friend_count++;
+ {
+ if ( (friend_count == minimum_friend_count - 1) &&
+ (GNUNET_YES != friends_only) )
+ whitelist_peers ();
+ friend_count++;
+ }
reschedule_hellos (pos);
}
"Connection to `%s' is not from a friend, forcing disconnect!\n",
GNUNET_i2s (&pos->id));
#endif
- force_disconnect (&pos->id);
+ force_disconnect (pos);
}
pos = pos->next;
}
next = pos->next;
if ( (GNUNET_NO == pos->is_friend) &&
(GNUNET_NO == pos->is_connected) &&
+ (GNUNET_NO == pos->is_blocked) &&
(0 == GNUNET_TIME_absolute_get_remaining (pos->blacklisted_until).value) )
free_peer (pos);
}