⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 identity.c

📁 GNUnet是一个安全的点对点网络框架
💻 C
📖 第 1 页 / 共 3 页
字号:
/*     This file is part of GNUnet.     (C) 2001, 2002, 2004, 2005, 2007 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 2, 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 identity/identity.c * @brief maintains list of known peers * * Code to maintain the list of currently known hosts (in memory * structure of data/hosts) and (temporary) blacklisting information * and a list of hellos that are temporary unless confirmed via PONG * (used to give the transport module the required information for the * PING). * * @author Christian Grothoff */#include "platform.h"#include "gnunet_util.h"#include "gnunet_protocols.h"#include "gnunet_directories.h"#include "gnunet_identity_service.h"#include "gnunet_transport_service.h"#include "identity.h"#include "hostkey.h"#define DEBUG_IDENTITY GNUNET_NO#define MAX_TEMP_HOSTS 32#define TRUSTDIR "data/credit/"#define HOST_DIR "data/hosts/"/** * Masks to keep track when the trust has changed and * to get the real trust value. */#define TRUST_REFRESH_MASK 0x80000000#define TRUST_ACTUAL_MASK  0x7FFFFFFF#define MAX_DATA_HOST_FREQ (5 * GNUNET_CRON_MINUTES)#define CRON_DATA_HOST_FREQ (15 * GNUNET_CRON_MINUTES)#define CRON_TRUST_FLUSH_FREQ (5 * GNUNET_CRON_MINUTES)#define CRON_DISCARD_HOSTS_INTERVAL (GNUNET_CRON_DAYS)#define CRON_DISCARDS_HOSTS_AFTER (3 * GNUNET_CRON_MONTHS)typedef struct{  GNUNET_PeerIdentity identity;  /**   * How long is this host blacklisted? (if at all)   */  GNUNET_CronTime until;  /**   * what would be the next increment for blacklisting?   */  GNUNET_CronTime delta;  /**   * hellos for the peer (maybe NULL)!   */  GNUNET_MessageHello **hellos;  unsigned int helloCount;  /**   * for which protocols is this host known?   */  unsigned short *protocols;  unsigned int protocolCount;  /**   * should we also reject incoming messages? (GNUNET_YES/GNUNET_NO)   */  int strict;  /**   * trust rating for this peer   */  unsigned int trust;} HostEntry;/** * The list of known hosts. */static HostEntry **hosts_ = NULL;/** * The current (allocated) size of knownHosts */static unsigned int sizeOfHosts_ = 0;/** * The number of actual entries in knownHosts */static unsigned int numberOfHosts_;/** * A lock for accessing knownHosts */static struct GNUNET_Mutex *lock_;/** * Directory where the hellos are stored in (data/hosts) */static char *networkIdDirectory;/** * Where do we store trust information? */static char *trustDirectory;/** * The list of temporarily known hosts */static HostEntry tempHosts[MAX_TEMP_HOSTS];static GNUNET_PeerIdentity myIdentity;static struct GNUNET_GE_Context *ectx;static GNUNET_CoreAPIForPlugins *coreAPI;/** * Get the filename under which we would store the GNUNET_MessageHello * for the given host and protocol. * @return filename of the form DIRECTORY/HOSTID.PROTOCOL */static char *getHostFileName (const GNUNET_PeerIdentity * id, unsigned short protocol){  GNUNET_EncName fil;  char *fn;  size_t n;  GNUNET_hash_to_enc (&id->hashPubKey, &fil);  n = strlen (networkIdDirectory) + sizeof (GNUNET_EncName) + 1 + 5 + 1;  fn = GNUNET_malloc (n);  GNUNET_snprintf (fn, n, "%s%s.%u", networkIdDirectory, (char *) &fil,                   protocol);  return fn;}/** * Find the host entry for the given peer.  Call * only when synchronized! * @return NULL if not found */static HostEntry *findHost (const GNUNET_PeerIdentity * id){  int i;  GNUNET_GE_ASSERT (ectx, numberOfHosts_ <= sizeOfHosts_);  for (i = 0; i < numberOfHosts_; i++)    if ((0 ==         memcmp (id, &hosts_[i]->identity, sizeof (GNUNET_PeerIdentity))))      return hosts_[i];  return NULL;}/** * Add a host to the list. * * @param identity the identity of the host * @param protocol the protocol for the host */static voidaddHostToKnown (const GNUNET_PeerIdentity * identity, unsigned short protocol){  HostEntry *entry;  int i;  GNUNET_EncName fil;  char *fn;  unsigned int trust;  GNUNET_GE_ASSERT (ectx, numberOfHosts_ <= sizeOfHosts_);  GNUNET_mutex_lock (lock_);  entry = findHost (identity);  if (entry == NULL)    {      entry = GNUNET_malloc (sizeof (HostEntry));      entry->identity = *identity;      entry->until = 0;      entry->delta = 30 * GNUNET_CRON_SECONDS;      entry->protocols = NULL;      entry->protocolCount = 0;      entry->strict = GNUNET_NO;      entry->hellos = NULL;      entry->helloCount = 0;      GNUNET_hash_to_enc (&identity->hashPubKey, &fil);      fn =        GNUNET_malloc (strlen (trustDirectory) + sizeof (GNUNET_EncName) + 1);      strcpy (fn, trustDirectory);      strcat (fn, (char *) &fil);      if ((GNUNET_disk_file_test (ectx,                                  fn) == GNUNET_YES) &&          (sizeof (unsigned int) ==           GNUNET_disk_file_read (ectx, fn, sizeof (unsigned int), &trust)))        {          entry->trust = ntohl (trust);        }      else        {          entry->trust = 0;        }      GNUNET_free (fn);      if (numberOfHosts_ == sizeOfHosts_)        GNUNET_array_grow (hosts_, sizeOfHosts_, sizeOfHosts_ + 32);      hosts_[numberOfHosts_++] = entry;    }  for (i = 0; i < entry->protocolCount; i++)    {      if (entry->protocols[i] == protocol)        {          GNUNET_mutex_unlock (lock_);          return;               /* already there */        }    }  GNUNET_array_grow (entry->protocols, entry->protocolCount,                     entry->protocolCount + 1);  entry->protocols[entry->protocolCount - 1] = protocol;  GNUNET_mutex_unlock (lock_);}/** * Increase the host credit by a value. * * @param hostId is the identity of the host * @param value is the int value by which the *  host credit is to be increased or decreased * @returns the actual change in trust (positive or negative) */static intchangeHostTrust (const GNUNET_PeerIdentity * hostId, int value){  HostEntry *host;  if (value == 0)    return 0;  GNUNET_mutex_lock (lock_);  host = findHost (hostId);  if (host == NULL)    {      addHostToKnown (hostId, GNUNET_TRANSPORT_PROTOCOL_NUMBER_NAT);      host = findHost (hostId);      if (host == NULL)        {          GNUNET_GE_BREAK (ectx, 0);          GNUNET_mutex_unlock (lock_);          return 0;        }    }  if (((int) (host->trust & TRUST_ACTUAL_MASK)) + value < 0)    {      value = -(host->trust & TRUST_ACTUAL_MASK);      host->trust = 0 | TRUST_REFRESH_MASK;     /* 0 remaining */    }  else    {      host->trust = ((host->trust & TRUST_ACTUAL_MASK) + value)        | TRUST_REFRESH_MASK;    }  GNUNET_mutex_unlock (lock_);  return value;}/** * Obtain the trust record of a peer. * * @param hostId the identity of the peer * @return the amount of trust we currently have in that peer */static unsigned intgetHostTrust (const GNUNET_PeerIdentity * hostId){  HostEntry *host;  unsigned int trust;  GNUNET_mutex_lock (lock_);  host = findHost (hostId);  if (host == NULL)    trust = 0;  else    trust = host->trust & TRUST_ACTUAL_MASK;  GNUNET_mutex_unlock (lock_);  return trust;}static intcronHelper (const char *filename, const char *dirname, void *unused){  GNUNET_PeerIdentity identity;  GNUNET_EncName id;  unsigned int protoNumber;  char *fullname;  GNUNET_GE_ASSERT (ectx, numberOfHosts_ <= sizeOfHosts_);  GNUNET_GE_ASSERT (ectx, sizeof (GNUNET_EncName) == 104);  if (2 == sscanf (filename, "%103c.%u", (char *) &id, &protoNumber))    {      id.encoding[sizeof (GNUNET_EncName) - 1] = '\0';      if (GNUNET_OK ==          GNUNET_enc_to_hash ((char *) &id, &identity.hashPubKey))        {          addHostToKnown (&identity, (unsigned short) protoNumber);          return GNUNET_OK;        }    }  fullname =    GNUNET_malloc (strlen (filename) + strlen (networkIdDirectory) + 1);  strcpy (fullname, networkIdDirectory);  strcat (fullname, filename);  if (GNUNET_disk_file_test (ectx, fullname) == GNUNET_YES)    {      if (0 == UNLINK (fullname))        GNUNET_GE_LOG (ectx,                       GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_ADMIN |                       GNUNET_GE_BULK,                       _                       ("File `%s' in directory `%s' does not match naming convention. "                        "Removed.\n"), filename, networkIdDirectory);      else        GNUNET_GE_LOG_STRERROR_FILE (ectx,                                     GNUNET_GE_ERROR | GNUNET_GE_USER |                                     GNUNET_GE_BULK, "unlink", fullname);    }  else if (GNUNET_disk_directory_test (ectx, fullname) == GNUNET_YES)    {      if (0 == RMDIR (fullname))        GNUNET_GE_LOG (ectx,                       GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_ADMIN |                       GNUNET_GE_BULK,                       _                       ("Directory `%s' in directory `%s' does not match naming convention. "                        "Removed.\n"), filename, networkIdDirectory);      else        GNUNET_GE_LOG_STRERROR_FILE (ectx,                                     GNUNET_GE_ERROR | GNUNET_GE_USER |                                     GNUNET_GE_BULK, "rmdir", fullname);    }  GNUNET_free (fullname);  return GNUNET_OK;}/** * Call this method periodically to scan data/hosts for new hosts. */static voidcronScanDirectoryDataHosts (void *unused){  static GNUNET_CronTime lastRun;  static int retries;  int count;  GNUNET_CronTime now;  now = GNUNET_get_time ();  if (lastRun + MAX_DATA_HOST_FREQ > now)    return;                     /* prevent scanning more than                                   once every 5 min */  lastRun = now;  count =    GNUNET_disk_directory_scan (ectx, networkIdDirectory, &cronHelper, NULL);  if (count <= 0)    {      retries++;      if ((retries & 32) > 0)        {          GNUNET_GE_LOG (ectx,                         GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_BULK,                         _("Still no peers found in `%s'!\n"),                         networkIdDirectory);        }    }  GNUNET_GE_ASSERT (ectx, numberOfHosts_ <= sizeOfHosts_);}/** * Obtain identity from publicPrivateKey. * @param pubKey the public key of the host * @param result address where to write the identity of the node */static voidgetPeerIdentity (const GNUNET_RSA_PublicKey * pubKey,                 GNUNET_PeerIdentity * result){  if (pubKey == NULL)    {      memset (&result, 0, sizeof (GNUNET_PeerIdentity));    }  else    {      GNUNET_hash (pubKey, sizeof (GNUNET_RSA_PublicKey),                   &result->hashPubKey);    }}/** * Add a host to the temporary list. */static voidaddHostTemporarily (const GNUNET_MessageHello * tmp){  static int tempHostsNextSlot;  GNUNET_MessageHello *msg;  HostEntry *entry;  int i;  int slot;  GNUNET_PeerIdentity have;  getPeerIdentity (&tmp->publicKey, &have);  if (0 != memcmp (&have, &tmp->senderIdentity, sizeof (GNUNET_PeerIdentity)))    {      GNUNET_GE_BREAK (NULL, 0);      return;    }  GNUNET_mutex_lock (lock_);  entry = findHost (&tmp->senderIdentity);  if ((entry != NULL) && (entry->helloCount > 0))    {      GNUNET_mutex_unlock (lock_);      return;    }  msg = GNUNET_malloc (GNUNET_sizeof_hello (tmp));  memcpy (msg, tmp, GNUNET_sizeof_hello (tmp));  slot = tempHostsNextSlot;  for (i = 0; i < MAX_TEMP_HOSTS; i++)    if (0 == memcmp (&tmp->senderIdentity,                     &tempHosts[i].identity, sizeof (GNUNET_PeerIdentity)))      slot = i;  if (slot == tempHostsNextSlot)    {      tempHostsNextSlot++;      if (tempHostsNextSlot >= MAX_TEMP_HOSTS)        tempHostsNextSlot = 0;    }  entry = &tempHosts[slot];  entry->identity = msg->senderIdentity;  entry->until = 0;  entry->delta = 0;  for (i = 0; i < entry->helloCount; i++)    GNUNET_free (entry->hellos[i]);  GNUNET_array_grow (entry->hellos, entry->helloCount, 1);  GNUNET_array_grow (entry->protocols, entry->protocolCount, 1);  entry->hellos[0] = msg;  entry->protocols[0] = ntohs (msg->protocol);  entry->strict = GNUNET_NO;  entry->trust = 0;  GNUNET_mutex_unlock (lock_);}/** * Delete a host from the list. */static voiddelHostFromKnown (const GNUNET_PeerIdentity * identity,                  unsigned short protocol){  HostEntry *entry;  char *fn;  int i;  int j;  GNUNET_GE_ASSERT (ectx, numberOfHosts_ <= sizeOfHosts_);  GNUNET_GE_ASSERT (ectx, protocol != GNUNET_TRANSPORT_PROTOCOL_NUMBER_ANY);  GNUNET_mutex_lock (lock_);  for (i = 0; i < numberOfHosts_; i++)    {      if ((0 == memcmp (identity,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -