/*
This file is part of GNUnet.
(C) 2007, 2008, 2009, 2010 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 3, or (at your
option) any later version.
GNUnet is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNUnet; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
/**
* @file topology/gnunet-daemon-topology.c
* @brief code for maintaining the mesh topology
* @author Christian Grothoff
*/
#include "platform.h"
#include "gnunet_constants.h"
#include "gnunet_core_service.h"
#include "gnunet_protocols.h"
#include "gnunet_peerinfo_service.h"
#include "gnunet_statistics_service.h"
#include "gnunet_transport_service.h"
#include "gnunet_util_lib.h"
/**
* Minimum required delay between calls to GNUNET_TRANSPORT_try_connect.
*/
#define MAX_CONNECT_FREQUENCY_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 250)
/**
* For how long do we blacklist a peer after a failed connection
* attempt? This is the baseline factor which is then multiplied by
* two to the power of the number of failed attempts.
*/
#define GREYLIST_AFTER_ATTEMPT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 1)
/**
* For how long do we blacklist a friend after a failed connection
* attempt? This is the baseline factor which is then multiplied by
* two to the power of the number of failed attempts.
*/
#define GREYLIST_AFTER_ATTEMPT_FRIEND GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2)
/**
* For how long do we blacklist anyone under any cirumstances at least after a failed connection
* attempt? This is the absolute minimum, regardless of what the calculation based on
* exponential backoff returns.
*/
#define GREYLIST_AFTER_ATTEMPT_MIN GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
/**
* For how long do we blacklist anyone under any cirumstances at most after a failed connection
* attempt? This is the absolute maximum, regardless of what the calculation based on
* exponential back-off returns.
*/
#define GREYLIST_AFTER_ATTEMPT_MAX GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 1)
/**
* At what frequency do we sent HELLOs to a peer?
*/
#define HELLO_ADVERTISEMENT_MIN_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
/**
* After what time period do we expire the HELLO Bloom filter?
*/
#define HELLO_ADVERTISEMENT_MIN_REPEAT_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4)
/**
* Record for neighbours, friends and blacklisted peers.
*/
struct Peer
{
/**
* Which peer is this entry about?
*/
struct GNUNET_PeerIdentity pid;
/**
* Our handle for the request to transmit HELLOs to this peer; NULL
* if no such request is pending.
*/
struct GNUNET_CORE_TransmitHandle *hello_req;
/**
* Pointer to the HELLO message of this peer; can be NULL.
*/
struct GNUNET_HELLO_Message *hello;
/**
* Bloom filter used to mark which peers already got the HELLO
* from this peer.
*/
struct GNUNET_CONTAINER_BloomFilter *filter;
/**
* Until what time should we not try to connect again
* to this peer?
*/
struct GNUNET_TIME_Absolute greylisted_until;
/**
* Next time we are allowed to transmit a HELLO to this peer?
*/
struct GNUNET_TIME_Absolute next_hello_allowed;
/**
* When should we reset the bloom filter of this entry?
*/
struct GNUNET_TIME_Absolute filter_expiration;
/**
* ID of task we use to wait for the time to send the next HELLO
* to this peer.
*/
GNUNET_SCHEDULER_TaskIdentifier hello_delay_task;
/**
* Task for issuing GNUNET_TRANSPORT_try_connect for this peer.
*/
GNUNET_SCHEDULER_TaskIdentifier attempt_connect_task;
/**
* ID of task we use to clear peers from the greylist.
*/
GNUNET_SCHEDULER_TaskIdentifier greylist_clean_task;
/**
* How often have we tried so far?
*/
unsigned int connect_attempts;
/**
* Is this peer listed here because he is a friend?
*/
int is_friend;
/**