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

📄 advertising.c

📁 GNUnet是一个安全的点对点网络框架
💻 C
📖 第 1 页 / 共 3 页
字号:
/*     This file is part of GNUnet.     (C) 2001, 2002, 2003, 2004, 2005, 2006, 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 advertising/advertising.c * @brief Cron-jobs that exchange hellos to ensure that the network is * connected (nodes know of each other).  This is implemented as * an application and not a service (since no API is provided for * clients to call on -- this just happens in the background). * * Nevertheless, every GNUnet peer should probably run advertising * at the moment. * * @author Christian Grothoff */#include "platform.h"#include "gnunet_util.h"#include "gnunet_protocols.h"#include "gnunet_identity_service.h"#include "gnunet_transport_service.h"#include "gnunet_pingpong_service.h"#include "gnunet_stats_service.h"#include "gnunet_topology_service.h"#include "bootstrap.h"/** * Send our hello to a random connected host on a regular basis. */#define HELLO_BROADCAST_FREQUENCY (2 * GNUNET_CRON_MINUTES)/** * From time to time, forward one hello from one peer to * a random other peer. */#define HELLO_FORWARD_FREQUENCY (45 * GNUNET_CRON_SECONDS)/** * Meanings of the bits in activeCronJobs (ACJ). */#define ACJ_NONE 0#define ACJ_ANNOUNCE 1#define ACJ_FORWARD 2#define ACJ_ALL (ACJ_ANNOUNCE | ACJ_FORWARD)#define DEBUG_ADVERTISING GNUNET_NOstatic GNUNET_CoreAPIForPlugins *coreAPI;static GNUNET_Transport_ServiceAPI *transport;static GNUNET_Identity_ServiceAPI *identity;static GNUNET_Pingpong_ServiceAPI *pingpong;static GNUNET_Topology_ServiceAPI *topology;static GNUNET_Stats_ServiceAPI *stats;static struct GNUNET_GE_Context *ectx;static int stat_hello_in;static int stat_hello_nat_in;static int stat_hello_verified;static int stat_hello_update;static int stat_hello_discard;static int stat_hello_no_transport;static int stat_hello_ping_busy;static int stat_hello_noselfad;static int stat_hello_send_error;static int stat_hello_out;static int stat_hello_fwd;static int stat_plaintextPingSent;/** * Which types of cron-jobs are currently scheduled * with cron? */static int activeCronJobs = ACJ_NONE;static GNUNET_CronTime lasthelloMsg = 0;static doublegetConnectPriority (){  double preference;  /* we should'nt give lots of bandwidth for hellos if we're close to     the connection goal */  preference = topology->getSaturation ();  if (preference <= 0.0001)    preference = 0xFFFF;  else    preference = 1 / preference;  /* always give some decent, but compared to (migrated) content     competitive amount of bandwidth to peers sending (valid)     hellos */  if (preference < 0.2)    preference = 0.2;  return preference;}static voidcallAddHost (void *cls){  GNUNET_MessageHello *hello = cls;  if (stats != NULL)    stats->change (stat_hello_verified, 1);  identity->addHost (hello);  GNUNET_free (hello);}/** * We have received a hello.  Verify (signature, integrity, * ping-pong) and store identity if ok. * * @param message the hello message * @return GNUNET_SYSERR on error, GNUNET_OK on success */static intreceivedhello (const GNUNET_PeerIdentity * sender,               const GNUNET_MessageHeader * message){  GNUNET_TSession *tsession;  GNUNET_MessageHello *copy;  GNUNET_PeerIdentity foreignId;  const GNUNET_MessageHello *msg;  GNUNET_MessageHeader *ping;  char *buffer;  int helloEnd;  int mtu;  int res;  GNUNET_CronTime now;  GNUNET_EncName enc;  /* first verify that it is actually a valid hello */  msg = (const GNUNET_MessageHello *) message;  if ((ntohs (msg->header.size) < sizeof (GNUNET_MessageHello)) ||      (ntohs (msg->header.size) != GNUNET_sizeof_hello (msg)))    {      GNUNET_GE_BREAK_OP (ectx, 0);      return GNUNET_SYSERR;    }  identity->getPeerIdentity (&msg->publicKey, &foreignId);  if (0 != memcmp (&msg->senderIdentity.hashPubKey,                   &foreignId.hashPubKey, sizeof (GNUNET_HashCode)))    {      GNUNET_GE_BREAK_OP (ectx, 0);      return GNUNET_SYSERR;     /* public key and host GNUNET_hash do not match */    }  if (GNUNET_SYSERR == GNUNET_RSA_verify (&msg->senderIdentity,                                          GNUNET_sizeof_hello (msg)                                          - sizeof (GNUNET_RSA_Signature)                                          - sizeof (GNUNET_RSA_PublicKey)                                          - sizeof (GNUNET_MessageHeader),                                          &msg->signature, &msg->publicKey))    {      IF_GELOG (ectx,                GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,                GNUNET_hash_to_enc (&msg->senderIdentity.hashPubKey, &enc));      GNUNET_GE_LOG (ectx,                     GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,                     _                     ("HELLO message from `%s' has an invalid signature. Dropping.\n"),                     (char *) &enc);      GNUNET_GE_BREAK_OP (ectx, 0);      return GNUNET_SYSERR;     /* message invalid */    }  if ((GNUNET_Int32Time) ntohl (msg->expiration_time) >      GNUNET_get_time_int32 (NULL) + GNUNET_MAX_HELLO_EXPIRES)    {      GNUNET_GE_LOG (ectx,                     GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,                     _                     ("HELLO message has expiration too far in the future. Dropping.\n"));      GNUNET_GE_BREAK_OP (ectx, 0);      return GNUNET_SYSERR;    }  if (GNUNET_SYSERR == transport->hello_verify (msg))    {#if DEBUG_ADVERTISING      IF_GELOG (ectx,                GNUNET_GE_INFO | GNUNET_GE_BULK | GNUNET_GE_USER,                GNUNET_hash_to_enc (&msg->senderIdentity.hashPubKey, &enc));      GNUNET_GE_LOG (ectx,                     GNUNET_GE_DEBUG | GNUNET_GE_BULK | GNUNET_GE_USER,                     "Transport verification of HELLO message from `%s' failed (%u).\n",                     &enc, ntohs (msg->protocol));#endif      return GNUNET_OK;         /* not good, but do process rest of message */    }  if (stats != NULL)    stats->change (stat_hello_in, 1);#if DEBUG_ADVERTISING  IF_GELOG (ectx,            GNUNET_GE_INFO | GNUNET_GE_REQUEST | GNUNET_GE_USER,            GNUNET_hash_to_enc (&msg->senderIdentity.hashPubKey, &enc));  GNUNET_GE_LOG (ectx,                 GNUNET_GE_INFO | GNUNET_GE_REQUEST | GNUNET_GE_USER,                 "HELLO advertisement from `%s' for protocol %d received.\n",                 &enc, ntohs (msg->protocol));#endif  if (ntohs (msg->protocol) == GNUNET_TRANSPORT_PROTOCOL_NUMBER_NAT)    {      /* We *can* not verify NAT.  Ever.  So all we         can do is just accept it.  The best thing         that we may do is check that it was not         forwarded by another peer (forwarding NAT         advertisements is invalid), but even that         check can not be done securely (since we         have to accept hellos in plaintext).  Thus         we take NAT advertisements at face value         (which is GNUNET_OK since we never attempt to         connect to a NAT). */      identity->addHost (msg);      if (stats != NULL)        stats->change (stat_hello_nat_in, 1);#if DEBUG_ADVERTISING      IF_GELOG (ectx,                GNUNET_GE_INFO | GNUNET_GE_REQUEST | GNUNET_GE_USER,                GNUNET_hash_to_enc (&msg->senderIdentity.hashPubKey, &enc));      GNUNET_GE_LOG (ectx,                     GNUNET_GE_INFO | GNUNET_GE_REQUEST | GNUNET_GE_USER,                     "HELLO advertisement from `%s' for NAT, no verification required.\n",                     &enc);#endif      return GNUNET_OK;    }  /* Then check if we have seen this hello before, if it is identical     except for the TTL, we trust it and do not play PING-PONG */  copy =    identity->identity2Hello (&foreignId, ntohs (msg->protocol), GNUNET_NO);  if (NULL != copy)    {      if ((ntohs (copy->senderAddressSize) ==           ntohs (msg->senderAddressSize)) &&          (0 == memcmp (&msg->MTU,                        &copy->MTU,                        sizeof (unsigned short) * 2 +                        sizeof (unsigned int) +                        ntohs (copy->senderAddressSize))))        {          /* ok, we've seen this one exactly like this before (at most the             TTL has changed); thus we can 'trust' it without playing             ping-pong */          identity->addHost (msg);          if (stats != NULL)            stats->change (stat_hello_update, 1);          GNUNET_free (copy);#if DEBUG_ADVERTISING          IF_GELOG (ectx,                    GNUNET_GE_INFO | GNUNET_GE_REQUEST | GNUNET_GE_USER,                    GNUNET_hash_to_enc (&msg->senderIdentity.hashPubKey,                                        &enc));          GNUNET_GE_LOG (ectx,                         GNUNET_GE_INFO | GNUNET_GE_REQUEST | GNUNET_GE_USER,                         "HELLO advertisement from `%s' for protocol %d updates old advertisement, no verification required.\n",                         &enc, ntohs (msg->protocol));#endif          return GNUNET_OK;        }#if DEBUG_ADVERTISING      GNUNET_GE_LOG (ectx,                     GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,                     "HELLO advertisement differs from prior knowledge,"                     " requireing ping-pong confirmation.\n");#endif      GNUNET_free (copy);    }  if (GNUNET_YES == GNUNET_GC_get_configuration_value_yesno (coreAPI->cfg,                                                             "GNUNETD",                                                             "PRIVATE-NETWORK",                                                             GNUNET_NO))    {      /* the option 'PRIVATE-NETWORK' can be used         to limit the connections of this peer to         peers of which the hostkey has been copied         by hand to data/hosts;  if this option is         given, GNUnet will not accept advertisements         of peers that the local node does not already         know about.  Note that in order for this         option to work, HOSTLISTURL should either         not be set at all or be set to a trusted         peer that only advertises the private network.         Also, the option does NOT work at the moment         if the NAT transport is loaded; for that,         a couple of lines above would need some minor         editing :-). */#if DEBUG_ADVERTISING      GNUNET_GE_LOG (ectx,                     GNUNET_GE_INFO | GNUNET_GE_BULK | GNUNET_GE_USER,                     "Private network, discarding unknown advertisements\n");

⌨️ 快捷键说明

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