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

📄 pingpong.c

📁 GNUnet是一个安全的点对点网络框架
💻 C
📖 第 1 页 / 共 2 页
字号:
/*     This file is part of GNUnet.     (C) 2001, 2002, 2003, 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 server/pingpong.c * @brief Pings a host and triggers an action if a reply is received. * @author Christian Grothoff */#include "platform.h"#include "gnunet_util.h"#include "gnunet_protocols.h"#include "gnunet_pingpong_service.h"#include "gnunet_identity_service.h"#include "gnunet_stats_service.h"#include "gnunet_transport_service.h"/** * Ping message (test if address actually corresponds to * the advertised GNUnet host. The receiver responds with * exactly the same message, except that it is now a pong. * This message can be send in plaintext and without padding * and typically does make little sense (except keepalive) * for an encrypted (authenticated) tunnel. * <br> * There is also no proof that the other side actually * has the acclaimed identity, the only thing that is * proved is that the other side can be reached via * the underlying protocol and that it is a GNUnet node. * <br> * The challenge prevents an inept adversary from sending * us a hello and then an arbitrary PONG reply (adversary * must at least be able to sniff our outbound traffic). */typedef struct{  GNUNET_MessageHeader header;  /**   * Which peer is the target of the ping? This is important since for   * plaintext-pings, we need to catch faulty advertisements that   * advertise a correct address but with the wrong public key.   */  GNUNET_PeerIdentity receiver;  /**   * The challenge is a (pseudo) random number that an adversary that   * wants to fake a pong message would have to guess. Since even if   * the number is guessed, the security impact is at most some wasted   * resources, 32 bit are more than enough.   */  int challenge;} P2P_pingpong_MESSAGE;#define DEBUG_PINGPONG GNUNET_NO#define MAX_PING_PONG 256typedef struct{  GNUNET_PeerIdentity receiverIdentity;  int challenge;  int plaintext;  GNUNET_CronJob method;  void *data;  GNUNET_Int32Time sendTime;} PingPongEntry;static PingPongEntry *pingPongs;static struct GNUNET_Mutex *pingPongLock;static GNUNET_CoreAPIForPlugins *coreAPI;static GNUNET_Transport_ServiceAPI *transport;static GNUNET_Identity_ServiceAPI *identity;static GNUNET_Stats_ServiceAPI *stats;static struct GNUNET_GE_Context *ectx;static int stat_encryptedPongReceived;static int stat_plaintextPongReceived;static int stat_pingReceived;static int stat_pingCreated;static int stat_pongSent;static int stat_plaintextPongSent;static int stat_plaintextPongFailed;static int stat_plaintextPingSent;static int stat_ciphertextPingSent;/** * We received a PING message, send the PONG reply. */static intpingReceived (const GNUNET_PeerIdentity * sender,              const GNUNET_MessageHeader * msg){  const P2P_pingpong_MESSAGE *pmsg;  P2P_pingpong_MESSAGE pong;  if (ntohs (msg->size) != sizeof (P2P_pingpong_MESSAGE))    {      GNUNET_GE_LOG (ectx,                     GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER |                     GNUNET_GE_DEVELOPER,                     _("Received malformed `%s' message. Dropping.\n"),                     "ping");      return GNUNET_SYSERR;    }  if (stats != NULL)    stats->change (stat_pingReceived, 1);  pmsg = (const P2P_pingpong_MESSAGE *) msg;  if (0 != memcmp (coreAPI->my_identity,                   &pmsg->receiver, sizeof (GNUNET_PeerIdentity)))    {      GNUNET_GE_LOG (ectx,                     GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_ADMIN,                     _("Received ping for another peer. Dropping.\n"));      return GNUNET_SYSERR;     /* not for us */    }#if DEBUG_PINGPONG  GNUNET_EncName enc;  GNUNET_hash_to_enc (&sender->hashPubKey, &enc);  GNUNET_GE_LOG (ectx,                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,                 "Received ping from peer %s.\n", &enc);#endif  pong = *pmsg;  pong.header.type = htons (GNUNET_P2P_PROTO_PONG);  if (stats != NULL)    stats->change (stat_pingReceived, 1);  coreAPI->ciphertext_send (sender, &pong.header, GNUNET_EXTREME_PRIORITY, 0);  /* send now! */  if (stats != NULL)    stats->change (stat_pongSent, 1);  return GNUNET_OK;}static intconnection_send_plaintext (const GNUNET_PeerIdentity * peer,                           const P2P_pingpong_MESSAGE * msg){  GNUNET_TSession *mytsession;  int ret;  mytsession = transport->connect_freely (peer, GNUNET_YES, __FILE__);  if (mytsession == NULL)    return GNUNET_SYSERR;  ret = coreAPI->plaintext_send (mytsession,                                 (char *) msg, sizeof (P2P_pingpong_MESSAGE));  transport->disconnect (mytsession, __FILE__);  return ret;}/** * We received a PING message, send the PONG reply and notify the * connection module that the session is still life. */static intplaintextPingReceived (const GNUNET_PeerIdentity * sender,                       const GNUNET_MessageHeader * hmsg,                       GNUNET_TSession * tsession){  GNUNET_EncName enc;  const P2P_pingpong_MESSAGE *pmsg;  P2P_pingpong_MESSAGE pong;  int ret;  if (ntohs (hmsg->size) != sizeof (P2P_pingpong_MESSAGE))    {      GNUNET_GE_LOG (ectx,                     GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER |                     GNUNET_GE_DEVELOPER,                     _("Received malformed `%s' message. Dropping.\n"),                     "ping");      GNUNET_GE_BREAK_OP (NULL, 0);      return GNUNET_SYSERR;    }  pmsg = (const P2P_pingpong_MESSAGE *) hmsg;  if (0 != memcmp (coreAPI->my_identity,                   &pmsg->receiver, sizeof (GNUNET_PeerIdentity)))    {      GNUNET_hash_to_enc (&sender->hashPubKey, &enc);      GNUNET_GE_LOG (ectx,                     GNUNET_GE_INFO | GNUNET_GE_REQUEST | GNUNET_GE_ADMIN,                     _("Received PING from `%s' not destined for us!\n"),                     &enc);      GNUNET_GE_BREAK_OP (NULL, 0);      return GNUNET_SYSERR;     /* not for us */    }#if DEBUG_PINGPONG  GNUNET_hash_to_enc (&sender->hashPubKey, &enc);  GNUNET_GE_LOG (ectx,                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,                 "Received plaintext ping from peer %s.\n", &enc);#endif  pong = *pmsg;  pong.header.type = htons (GNUNET_P2P_PROTO_PONG);  /* allow using a different transport for sending the reply, the     transport may have been uni-directional! */  ret = GNUNET_SYSERR;  if (tsession != NULL)    ret = coreAPI->plaintext_send (tsession,                                   (char *) &pong,                                   sizeof (P2P_pingpong_MESSAGE));  if (ret != GNUNET_OK)    ret = connection_send_plaintext (sender, &pong);  if (ret == GNUNET_OK)    {      if (stats != NULL)        stats->change (stat_plaintextPongSent, 1);    }  else    {      if (stats != NULL)        stats->change (stat_plaintextPongFailed, 1);    }  return ret;}/** * Handler for a pong. */static intpongReceived (const GNUNET_PeerIdentity * sender,              const GNUNET_MessageHeader * msg){  int i;  const P2P_pingpong_MESSAGE *pmsg;  PingPongEntry *entry;  int matched;#if DEBUG_PINGPONG  GNUNET_EncName enc;#endif  pmsg = (const P2P_pingpong_MESSAGE *) msg;  if ((ntohs (msg->size) != sizeof (P2P_pingpong_MESSAGE)) ||      (0 != memcmp (sender, &pmsg->receiver, sizeof (GNUNET_PeerIdentity))))    {      GNUNET_GE_LOG (ectx,                     GNUNET_GE_WARNING | GNUNET_GE_BULK | GNUNET_GE_USER |                     GNUNET_GE_DEVELOPER,                     _("Received malformed `%s' message. Dropping.\n"),                     "pong");      return GNUNET_SYSERR;     /* bad pong */    }#if DEBUG_PINGPONG  GNUNET_hash_to_enc (&sender->hashPubKey, &enc);  GNUNET_GE_LOG (ectx,                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,                 "Received PONG from `%s'.\n", &enc);#endif  matched = 0;  if (stats != NULL)    stats->change (stat_encryptedPongReceived, 1);  GNUNET_mutex_lock (pingPongLock);  for (i = 0; i < MAX_PING_PONG; i++)    {      entry = &pingPongs[i];      if (((int) ntohl (pmsg->challenge) == entry->challenge) &&          (0 == memcmp (sender,                        &entry->receiverIdentity,                        sizeof (GNUNET_PeerIdentity)))          && (entry->plaintext == GNUNET_NO))        {          entry->method (entry->data);

⌨️ 快捷键说明

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