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

📄 messaging.c

📁 GNUnet是一个安全的点对点网络框架
💻 C
📖 第 1 页 / 共 2 页
字号:
/*     This file is part of GNUnet.     (C) 2008 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 applications/chat/lib/messaging.c * @brief convenience API for sending and receiving chat messages * @author Christian Grothoff * @author Nathan Evans */#include "platform.h"#include "gnunet_util.h"#include "gnunet_protocols.h"#include "gnunet_chat_lib.h"#include "gnunet_directories.h"#include "chat.h"#define NICK_IDENTITY_PREFIX ".chat_identity_"/** * Handle for a (joined) chat room. */struct GNUNET_CHAT_Room{  struct GNUNET_ClientServerConnection *sock;  struct GNUNET_ThreadHandle *listen_thread;  struct GNUNET_GE_Context *ectx;  struct GNUNET_GC_Configuration *cfg;  struct GNUNET_MetaData *member_info;  char *room_name;  GNUNET_RSA_PrivateKeyEncoded *my_private_key;  GNUNET_CHAT_MessageCallback message_callback;  void *message_callback_cls;  GNUNET_CHAT_MemberListCallback member_list_callback;  void *member_list_callback_cls;  GNUNET_CHAT_MessageConfirmation confirmation_callback;  void *confirmation_cls;  int shutdown_flag;  unsigned int sequence_number;  unsigned int msg_options;};/** * Linked list of members in the chat room. */struct MemberList{  struct MemberList *next;  /**   * Description of the member.   */  struct GNUNET_MetaData *meta;  /**   * Member ID (pseudonym).   */  GNUNET_HashCode id;};static intGNUNET_CHAT_rejoin_room (struct GNUNET_CHAT_Room *chat_room){  CS_chat_MESSAGE_JoinRequest *join_msg;  unsigned int size_of_join;  unsigned int room_len;  unsigned int meta_len;  char *room;  meta_len =    GNUNET_meta_data_get_serialized_size (chat_room->member_info, GNUNET_YES);  room_len = strlen (chat_room->room_name);  size_of_join = sizeof (CS_chat_MESSAGE_JoinRequest) + meta_len    + room_len + ntohs (chat_room->my_private_key->len) -    sizeof (GNUNET_RSA_PrivateKeyEncoded);  if (size_of_join >= GNUNET_MAX_BUFFER_SIZE - 8)    return GNUNET_SYSERR;  join_msg = GNUNET_malloc (size_of_join);  join_msg->header.size = htons (size_of_join);  join_msg->header.type = htons (GNUNET_CS_PROTO_CHAT_JOIN_REQUEST);  join_msg->msg_options = htonl (chat_room->msg_options);  join_msg->room_name_len = htons (room_len);  join_msg->reserved = htons (0);  memcpy (&join_msg->private_key,          chat_room->my_private_key, ntohs (chat_room->my_private_key->len));  room = (char *) &join_msg[1];  room +=    ntohs (chat_room->my_private_key->len) -    sizeof (GNUNET_RSA_PrivateKeyEncoded);  memcpy (room, chat_room->room_name, room_len);  if (GNUNET_SYSERR ==      GNUNET_meta_data_serialize (chat_room->ectx,                                  chat_room->member_info,                                  &room[room_len], meta_len, GNUNET_YES))    {      GNUNET_free (join_msg);      return GNUNET_SYSERR;    }  if (GNUNET_SYSERR ==      GNUNET_client_connection_write (chat_room->sock, &join_msg->header))    {      GNUNET_free (join_msg);      return GNUNET_SYSERR;    }  GNUNET_free (join_msg);  return GNUNET_OK;}/** * Listen for incoming messages on this chat room.  When received, * call the proper client callback.  Also, support servers going * away/coming back (i.e. rejoin chat room to keep server state up to * date)... */static void *poll_thread (void *rcls){  struct GNUNET_CHAT_Room *room = rcls;  GNUNET_MessageHeader *reply;  CS_chat_MESSAGE_ConfirmationReceipt *receipt;  CS_chat_MESSAGE_LeaveNotification *leave_msg;  CS_chat_MESSAGE_JoinNotification *join_msg;  CS_chat_MESSAGE_ReceiveNotification *received_msg;  GNUNET_HashCode id;  struct GNUNET_MetaData *meta;  struct MemberList *members;  struct MemberList *pos;  struct MemberList *prev;  unsigned int size;  unsigned int meta_len;  unsigned int msg_len;  char *message_content;  int disconnected;  int malformed;  int ret;  disconnected = GNUNET_NO;  malformed = GNUNET_NO;  ret = GNUNET_OK;  reply = NULL;  members = NULL;  while ((ret == GNUNET_OK) && (room->shutdown_flag != GNUNET_YES))    {      if (malformed)        {          GNUNET_GE_BREAK (NULL, 0);          GNUNET_client_connection_close_temporarily (room->sock);          disconnected = GNUNET_YES;          malformed = GNUNET_NO;        }      if (reply != NULL)        {          GNUNET_free (reply);          reply = NULL;        }      if (disconnected)        {          GNUNET_thread_sleep (15 * GNUNET_CRON_SECONDS);          if (GNUNET_client_connection_ensure_connected (room->sock) ==              GNUNET_OK)            {              /* send join! */              disconnected = GNUNET_NO;              GNUNET_CHAT_rejoin_room (room);              continue;            }          else            break;        }      reply = NULL;      if (GNUNET_OK != GNUNET_client_connection_read (room->sock, &reply))        {          disconnected = GNUNET_YES;          continue;        }      size = ntohs (reply->size);      switch (ntohs (reply->type))        {        case GNUNET_CS_PROTO_CHAT_JOIN_NOTIFICATION:          if (size < sizeof (CS_chat_MESSAGE_JoinNotification))            {              malformed = GNUNET_YES;              continue;            }          join_msg = (CS_chat_MESSAGE_JoinNotification *) reply;          meta_len = size - sizeof (CS_chat_MESSAGE_JoinNotification);          meta = GNUNET_meta_data_deserialize (room->ectx,                                               (const char *)                                               &join_msg[1], meta_len);          if (meta == NULL)            {              malformed = GNUNET_YES;              continue;            }          pos = GNUNET_malloc (sizeof (struct MemberList));          pos->meta = meta;          GNUNET_hash (&join_msg->public_key,                       sizeof (GNUNET_RSA_PublicKey), &pos->id);          GNUNET_pseudonym_add (room->ectx, room->cfg, &pos->id, meta);          room->member_list_callback (room->member_list_callback_cls,                                      meta, &join_msg->public_key,                                      ntohl (join_msg->msg_options));          pos->next = members;          members = pos;          break;        case GNUNET_CS_PROTO_CHAT_LEAVE_NOTIFICATION:          if (size < sizeof (CS_chat_MESSAGE_LeaveNotification))            {              malformed = GNUNET_YES;              continue;            }          leave_msg = (CS_chat_MESSAGE_LeaveNotification *) reply;          room->member_list_callback (room->member_list_callback_cls,                                      NULL, &leave_msg->user,                                      GNUNET_CHAT_MSG_OPTION_NONE);          GNUNET_hash (&leave_msg->user, sizeof (GNUNET_RSA_PublicKey), &id);          prev = NULL;          pos = members;          while ((pos != NULL) &&                 (0 != memcmp (&pos->id, &id, sizeof (GNUNET_HashCode))))            {              prev = pos;              pos = pos->next;            }          GNUNET_GE_ASSERT (NULL, pos != NULL);          if (prev == NULL)            members = pos->next;          else            prev->next = pos->next;          GNUNET_meta_data_destroy (pos->meta);          GNUNET_free (pos);          break;        case GNUNET_CS_PROTO_CHAT_MESSAGE_NOTIFICATION:          if (size < sizeof (CS_chat_MESSAGE_ReceiveNotification))            {              malformed = GNUNET_YES;              continue;            }          received_msg = (CS_chat_MESSAGE_ReceiveNotification *) reply;          msg_len = size - sizeof (CS_chat_MESSAGE_ReceiveNotification);          message_content = GNUNET_malloc (msg_len + 1);          memcpy (message_content, &received_msg[1], msg_len);          message_content[msg_len] = '\0';          pos = members;          while ((pos != NULL) &&                 (0 != memcmp (&pos->id,

⌨️ 快捷键说明

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