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

📄 cs.c

📁 GNUnet是一个安全的点对点网络框架
💻 C
字号:
/*      This file is part of GNUnet      Copyright (C) 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 module/cs.c * @brief DHT application protocol using the DHT service. *   This is merely for the dht-client library.  The code *   of this file is mostly converting from and to TCP messages. * @author Marko Räihä, Christian Grothoff */#include "platform.h"#include "gnunet_core.h"#include "gnunet_protocols.h"#include "dht.h"#include "gnunet_dht_service.h"#include "service.h"#define DEBUG_CS GNUNET_NO/** * Global core API. */static GNUNET_CoreAPIForPlugins *coreAPI;/** * Reference to the DHT service API. */static GNUNET_DHT_ServiceAPI *dhtAPI;/** * Type of the linked list that is used by CS to * keep track of clients and their pending GET * requests. */struct DHT_CLIENT_GET_RECORD{  struct DHT_CLIENT_GET_RECORD *next;  struct GNUNET_ClientHandle *client;  struct GNUNET_DHT_GetHandle *get_record;};/** * Linked list of active GET requests. */static struct DHT_CLIENT_GET_RECORD *getRecords;/** * Lock. */static struct GNUNET_Mutex *lock;/** * CS handler for inserting <key,value>-pair into DHT-table. */static intcsPut (struct GNUNET_ClientHandle *client,       const GNUNET_MessageHeader * message){  const CS_dht_request_put_MESSAGE *req;  unsigned int size;  if (ntohs (message->size) < sizeof (CS_dht_request_put_MESSAGE))    {      GNUNET_GE_BREAK (NULL, 0);      return GNUNET_SYSERR;    }  req = (const CS_dht_request_put_MESSAGE *) message;  size = ntohs (req->header.size) - sizeof (CS_dht_request_put_MESSAGE);  GNUNET_GE_ASSERT (NULL, size < GNUNET_MAX_BUFFER_SIZE);  dhtAPI->put (&req->key, ntohl (req->type), size, (const char *) &req[1]);  return GNUNET_OK;}static intget_result (const GNUNET_HashCode * key,            unsigned int type,            unsigned int size, const char *value, void *cls){  struct DHT_CLIENT_GET_RECORD *record = cls;  CS_dht_request_put_MESSAGE *msg;  size_t n;  n = sizeof (CS_dht_request_put_MESSAGE) + size;  if (n > GNUNET_MAX_BUFFER_SIZE)    {      GNUNET_GE_BREAK (NULL, 0);      return GNUNET_SYSERR;    }  msg = GNUNET_malloc (n);  msg->header.size = htons (n);  msg->header.type = htons (GNUNET_CS_PROTO_DHT_REQUEST_PUT);  msg->type = htonl (type);  msg->key = *key;  memcpy (&msg[1], value, size);  if (GNUNET_OK !=      coreAPI->cs_send_message (record->client, &msg->header, GNUNET_YES))    {      GNUNET_GE_LOG (coreAPI->ectx,                     GNUNET_GE_ERROR | GNUNET_GE_IMMEDIATE | GNUNET_GE_USER,                     _("`%s' failed. Terminating connection to client.\n"),                     "cs_send_to_client");      coreAPI->cs_disconnect_now (record->client);    }  GNUNET_free (msg);  return GNUNET_OK;}/** * CS handler for getting key from DHT. */static intcsGet (struct GNUNET_ClientHandle *client,       const GNUNET_MessageHeader * message){  const CS_dht_request_get_MESSAGE *get;  struct DHT_CLIENT_GET_RECORD *cpc;  if (ntohs (message->size) != sizeof (CS_dht_request_get_MESSAGE))    {      GNUNET_GE_BREAK (NULL, 0);      return GNUNET_SYSERR;    }  get = (const CS_dht_request_get_MESSAGE *) message;  cpc = GNUNET_malloc (sizeof (struct DHT_CLIENT_GET_RECORD));  cpc->client = client;  cpc->get_record = dhtAPI->get_start (ntohl (get->type),                                       &get->key, &get_result, cpc);  GNUNET_mutex_lock (lock);  cpc->next = getRecords;  getRecords = cpc;  GNUNET_mutex_unlock (lock);  return GNUNET_OK;}/** * CS handler for stopping existing get from DHT. */static intcsGetEnd (struct GNUNET_ClientHandle *client,          const GNUNET_MessageHeader * message){  const CS_dht_request_get_MESSAGE *get;  struct DHT_CLIENT_GET_RECORD *pos;  struct DHT_CLIENT_GET_RECORD *prev;  if (ntohs (message->size) != sizeof (CS_dht_request_get_MESSAGE))    {      GNUNET_GE_BREAK (NULL, 0);      return GNUNET_SYSERR;    }  get = (const CS_dht_request_get_MESSAGE *) message;  GNUNET_mutex_lock (lock);  pos = getRecords;  prev = NULL;  while (pos != NULL)    {      if ((memcmp (pos->client, client, sizeof (client)) == 0) &&          (memcmp           (&pos->get_record->key, &get->key, sizeof (GNUNET_HashCode)))          && (ntohs (get->type) == pos->get_record->type))        break;      prev = pos;      pos = pos->next;    }  if (pos == NULL)    {      GNUNET_mutex_unlock (lock);      return GNUNET_OK;    }  if (prev == NULL)    getRecords = pos->next;  else    prev->next = pos->next;  GNUNET_mutex_unlock (lock);  dhtAPI->get_stop (pos->get_record);  GNUNET_free (pos);  return GNUNET_OK;}/** * CS handler for handling exiting client.  Triggers * get_stop for all operations that rely on this client. */static voidcsClientExit (struct GNUNET_ClientHandle *client){  struct GNUNET_DHT_GetHandle *gr;  struct DHT_CLIENT_GET_RECORD *pos;  struct DHT_CLIENT_GET_RECORD *prev;  GNUNET_mutex_lock (lock);  pos = getRecords;  prev = NULL;  while (pos != NULL)    {      if (pos->client == client)        {          gr = pos->get_record;          if (prev == NULL)            getRecords = pos->next;          else            prev->next = pos->next;          GNUNET_mutex_unlock (lock);          dhtAPI->get_stop (gr);          GNUNET_free (pos);          GNUNET_mutex_lock (lock);          pos = getRecords;          continue;        }      prev = pos;      pos = pos->next;    }  GNUNET_mutex_unlock (lock);}intinitialize_module_dht (GNUNET_CoreAPIForPlugins * capi){  int status;  dhtAPI = capi->service_request ("dht");  if (dhtAPI == NULL)    return GNUNET_SYSERR;  coreAPI = capi;  GNUNET_GE_LOG (coreAPI->ectx,                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,                 _("`%s' registering client handlers: %d %d\n"),                 "dht", GNUNET_CS_PROTO_DHT_REQUEST_PUT,                 GNUNET_CS_PROTO_DHT_REQUEST_GET);  status = GNUNET_OK;  lock = GNUNET_mutex_create (GNUNET_NO);  if (GNUNET_SYSERR ==      capi->cs_handler_register (GNUNET_CS_PROTO_DHT_REQUEST_PUT, &csPut))    status = GNUNET_SYSERR;  if (GNUNET_SYSERR ==      capi->cs_handler_register (GNUNET_CS_PROTO_DHT_REQUEST_GET, &csGet))    status = GNUNET_SYSERR;  if (GNUNET_SYSERR ==      capi->cs_handler_register (GNUNET_CS_PROTO_DHT_REQUEST_GET_END,                                 &csGetEnd))    status = GNUNET_SYSERR;  if (GNUNET_SYSERR == capi->cs_disconnect_handler_register (&csClientExit))    status = GNUNET_SYSERR;  GNUNET_GE_ASSERT (capi->ectx,                    0 == GNUNET_GC_set_configuration_value_string (capi->cfg,                                                                   capi->ectx,                                                                   "ABOUT",                                                                   "dht",                                                                   gettext_noop                                                                   ("Enables efficient non-anonymous routing")));  return status;}/** * Find the record, remove it from the linked list * and cancel the operation with the DHT API. */static voidkill_record (void *cls){  struct DHT_CLIENT_GET_RECORD *record = cls;  struct DHT_CLIENT_GET_RECORD *pos;  struct DHT_CLIENT_GET_RECORD *prev;  GNUNET_mutex_lock (lock);  pos = getRecords;  prev = NULL;  while (pos != NULL)    {      if (pos == record)        break;      prev = pos;      pos = pos->next;    }  if (pos == NULL)    {      GNUNET_mutex_unlock (lock);      return;    }  if (prev == NULL)    getRecords = pos->next;  else    prev->next = pos->next;  GNUNET_mutex_unlock (lock);  dhtAPI->get_stop (record->get_record);  GNUNET_free (record);}/** * Unregisters handlers, cleans memory structures etc when node exits. */intdone_module_dht (){  int status;  status = GNUNET_OK;  GNUNET_GE_LOG (coreAPI->ectx,                 GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,                 "DHT: shutdown\n");  if (GNUNET_OK !=      coreAPI->cs_handler_unregister (GNUNET_CS_PROTO_DHT_REQUEST_PUT,                                      &csPut))    status = GNUNET_SYSERR;  if (GNUNET_OK !=      coreAPI->cs_handler_unregister (GNUNET_CS_PROTO_DHT_REQUEST_GET,                                      &csGet))    status = GNUNET_SYSERR;  if (GNUNET_OK != coreAPI->cs_disconnect_handler_unregister (&csClientExit))    status = GNUNET_SYSERR;  while (getRecords != NULL)    kill_record (getRecords);  coreAPI->service_release (dhtAPI);  dhtAPI = NULL;  coreAPI = NULL;  GNUNET_mutex_destroy (lock);  return status;}/* end of cs.c */

⌨️ 快捷键说明

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