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

📄 advertising.c

📁 GNUnet是一个安全的点对点网络框架
💻 C
📖 第 1 页 / 共 3 页
字号:
#endif      return GNUNET_SYSERR;    }  /* Ok, must play PING-PONG. Add the hello to the temporary     (in-memory only) buffer to make it available for a short     time in order to play PING-PONG */  identity->addHostTemporarily (msg);  now = GNUNET_get_time ();  if ((sender != NULL) &&      ((now - lasthelloMsg) / GNUNET_CRON_SECONDS) *      (GNUNET_network_monitor_get_limit (coreAPI->load_monitor,                                         GNUNET_ND_DOWNLOAD))      < GNUNET_sizeof_hello (msg) * 10)    {      /* do not use more than about 10% of the         available bandwidth to VERIFY hellos (by sending         our own with a PING).  This does not affect         the hello advertising.  Sure, we should not         advertise much more than what other peers         can verify, but the problem is that buggy/         malicious peers can spam us with hellos, and         we don't want to follow that up with massive         hello-ing by ourselves. */#if DEBUG_ADVERTISING      GNUNET_GE_LOG (ectx,                     GNUNET_GE_INFO | GNUNET_GE_BULK | GNUNET_GE_USER,                     "Not enough resources to verify HELLO message at this time (%u * %u < %u * 10)\n",                     (unsigned int) ((now - lasthelloMsg) /                                     GNUNET_CRON_SECONDS),                     (unsigned int)                     GNUNET_network_monitor_get_limit (coreAPI->load_monitor,                                                       GNUNET_ND_DOWNLOAD),                     (unsigned int) GNUNET_sizeof_hello (msg));#endif      if (stats != NULL)        stats->change (stat_hello_discard, 1);      return GNUNET_SYSERR;    }  lasthelloMsg = now;  /* Establish session as advertised in the hello */  tsession = transport->connect (msg, __FILE__, GNUNET_NO);  if (tsession == NULL)    {      if (stats != NULL)        stats->change (stat_hello_no_transport, 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,                     "Failed to connect to `%s'.  Verification failed.\n",                     &enc);#endif      return GNUNET_SYSERR;     /* could not connect */    }  /* build message to send, ping must contain return-information,     such as a selection of our hellos... */  mtu = transport->mtu_get (tsession->ttype);  if (mtu == 0)    {      mtu = 2048;               /* bound size */    }  else    {      GNUNET_GE_ASSERT (ectx, mtu > GNUNET_P2P_MESSAGE_OVERHEAD);      mtu -= GNUNET_P2P_MESSAGE_OVERHEAD;    }  copy = GNUNET_malloc (GNUNET_sizeof_hello (msg));  memcpy (copy, msg, GNUNET_sizeof_hello (msg));  ping = pingpong->pingUser (&msg->senderIdentity,                             &callAddHost, copy, GNUNET_YES, rand ());  if (ping == NULL)    {      res = GNUNET_SYSERR;      GNUNET_GE_LOG (ectx,                     GNUNET_GE_INFO | GNUNET_GE_REQUEST | GNUNET_GE_USER,                     _("Could not send HELLO+PING, ping buffer full.\n"));      transport->disconnect (tsession, __FILE__);      if (stats != NULL)        stats->change (stat_hello_ping_busy, 1);      return GNUNET_SYSERR;    }  buffer = GNUNET_malloc (mtu);  if (mtu > ntohs (ping->size))    {      helloEnd =        transport->hello_advertisements_get (mtu - ntohs (ping->size),                                             buffer);      GNUNET_GE_ASSERT (ectx, mtu - ntohs (ping->size) >= helloEnd);    }  else    {      helloEnd = -2;    }  if (helloEnd <= 0)    {      GNUNET_GE_LOG (ectx,                     GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,                     _                     ("Failed to create an advertisement for this peer. Will not send PING.\n"));      GNUNET_free (buffer);      if (stats != NULL)        stats->change (stat_hello_noselfad, 1);      transport->disconnect (tsession, __FILE__);#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,                     "Failed to connect advertisement for myself.  Verification failed.\n",                     &enc);#endif      return GNUNET_SYSERR;    }  res = GNUNET_OK;  memcpy (&buffer[helloEnd], ping, ntohs (ping->size));  helloEnd += ntohs (ping->size);  GNUNET_free (ping);  /* ok, finally we can send! */  if ((res == GNUNET_OK) &&      (GNUNET_SYSERR == coreAPI->plaintext_send (tsession, buffer, helloEnd)))    {      if (stats != NULL)        stats->change (stat_hello_send_error, 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,                     "Failed to transmit advertisement for myself.  Verification failed.\n",                     &enc);#endif      res = GNUNET_SYSERR;    }  if (res == GNUNET_OK)    {      if (stats != NULL)        stats->change (stat_plaintextPingSent, 1);    }  GNUNET_free (buffer);  if (GNUNET_SYSERR == transport->disconnect (tsession, __FILE__))    res = GNUNET_SYSERR;  return res;}typedef struct{  /* the hello message */  GNUNET_MessageHello *m;  /* send the hello in 1 out of n cases */  int n;} SendData;static intbroadcastHelper (const GNUNET_PeerIdentity * hi,                 const unsigned short proto, int confirmed, void *cls){  SendData *sd = cls;  GNUNET_MessageHello *hello;  GNUNET_TSession *tsession;  int prio;#if DEBUG_ADVERTISING  GNUNET_EncName other;#endif  if (confirmed == GNUNET_NO)    return GNUNET_OK;  if (proto == GNUNET_TRANSPORT_PROTOCOL_NUMBER_NAT)    {      sd->n--;      return GNUNET_OK;         /* don't advertise NAT addresses via broadcast */    }  if ((sd->n != 0)      && (GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, sd->n) != 0))    return GNUNET_OK;#if DEBUG_ADVERTISING  IF_GELOG (ectx,            GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,            GNUNET_hash_to_enc (&hi->hashPubKey, &other));  GNUNET_GE_LOG (ectx,                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,                 "Entering with target `%s'.\n", &other);#endif  if (0 == memcmp (hi, coreAPI->my_identity, sizeof (GNUNET_PeerIdentity)))    return GNUNET_OK;           /* never advertise to myself... */  prio = (int) getConnectPriority ();  if (prio >= GNUNET_EXTREME_PRIORITY)    prio = GNUNET_EXTREME_PRIORITY / 4;  if (GNUNET_OK == coreAPI->p2p_connection_status_check (hi, NULL, NULL))    {      coreAPI->ciphertext_send (hi, &sd->m->header, prio,                                HELLO_BROADCAST_FREQUENCY);      if (stats != NULL)        stats->change (stat_hello_out, 1);      return GNUNET_OK;    }  /* with even lower probability (with n peers     trying to contact with a probability of 1/n^2,     we get a probability of 1/n for this, which     is what we want: fewer attempts to contact fresh     peers as the network grows): */  if ((sd->n != 0)      && (GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, sd->n) != 0))    return GNUNET_OK;  /* establish short-lived connection, send, tear down */  hello = identity->identity2Hello (hi, proto, GNUNET_NO);  if (NULL == hello)    return GNUNET_OK;  tsession = transport->connect (hello, __FILE__, GNUNET_YES);  GNUNET_free (hello);  if (tsession == NULL)    return GNUNET_OK;           /* could not connect */  if (stats != NULL)    stats->change (stat_hello_out, 1);  coreAPI->plaintext_send (tsession,                           (char *) &sd->m->header,                           GNUNET_sizeof_hello (sd->m));  transport->disconnect (tsession, __FILE__);  return GNUNET_OK;}/** * Tell a couple of random hosts on the currentKnownHost list * that we exist (called for each transport)... */static voidbroadcasthelloTransport (GNUNET_TransportAPI * tapi, void *cls){  const int *prob = cls;  SendData sd;  GNUNET_CronTime now;  if (GNUNET_network_monitor_get_load      (coreAPI->load_monitor, GNUNET_ND_UPLOAD) > 100)    return;                     /* network load too high... */  if (((*prob) != 0)      && (0 != GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, *prob)))    return;                     /* ignore */  now = GNUNET_get_time ();  sd.n = identity->forEachHost (now, NULL, NULL);       /* just count */  sd.m = transport->hello_create (tapi->protocol_number);  if (sd.m == NULL)    return;#if DEBUG_ADVERTISING  GNUNET_GE_LOG (ectx,                 GNUNET_GE_INFO | GNUNET_GE_REQUEST | GNUNET_GE_USER,                 _("Advertising my transport %d to selected peers.\n"),                 tapi->protocol_number);#endif  identity->addHost (sd.m);  if (sd.n < 1)    {      if (identity->forEachHost (0, NULL, NULL) == 0)        GNUNET_GE_LOG (ectx,                       GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER,                       _("Announcing ourselves pointless: "                         "no other peers are known to us so far.\n"));      GNUNET_free (sd.m);      return;                   /* no point in trying... */    }  identity->forEachHost (now, &broadcastHelper, &sd);  GNUNET_free (sd.m);}/** * Tell a couple of random hosts on the currentKnownHost list * that we exist... */static voidbroadcasthello (void *unused){  unsigned int i;  if (GNUNET_network_monitor_get_load      (coreAPI->load_monitor, GNUNET_ND_UPLOAD) > 100)    return;                     /* network load too high... */  if (GNUNET_cpu_get_load (coreAPI->ectx, coreAPI->cfg) > 100)    return;                     /* CPU load too high... */  i = transport->iterate_available (NULL, NULL);  if (i > 0)    transport->iterate_available (&broadcasthelloTransport, &i);}typedef struct{  GNUNET_MessageHello *msg;  int prob;} FCC;static voidforwardCallback (const GNUNET_PeerIdentity * peer, void *cls){  FCC *fcc = cls;  if (GNUNET_network_monitor_get_load      (coreAPI->load_monitor, GNUNET_ND_UPLOAD) > 100)    return;                     /* network load too high... */  if ((fcc->prob != 0)      && (GNUNET_random_u32 (GNUNET_RANDOM_QUALITY_WEAK, fcc->prob) != 0))    return;                     /* only forward with a certain chance */  if (0 == memcmp (&peer->hashPubKey,                   &fcc->msg->senderIdentity.hashPubKey,                   sizeof (GNUNET_HashCode)))    return;                     /* do not bounce the hello of a peer back                                   to the same peer! */  if (stats != NULL)    stats->change (stat_hello_fwd, 1);  coreAPI->ciphertext_send (peer, &fcc->msg->header, 0, /* priority */                            HELLO_BROADCAST_FREQUENCY);}/** * Forward hellos from all known hosts to all connected hosts. */

⌨️ 快捷键说明

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