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

📄 gnutella.c

📁 Serveez是一个服务器框架
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * gnutella.c - gnutella protocol implementation * * Copyright (C) 2000, 2001 Stefan Jahn <stefan@lkcc.org> * * This 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. *  * This software 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 this package; see the file COPYING.  If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA.   * * $Id: gnutella.c,v 1.42 2001/08/01 10:16:22 ela Exp $ * */#if HAVE_CONFIG_H# include <config.h>#endif#if ENABLE_GNUTELLA#define _GNU_SOURCE#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <sys/stat.h>#if HAVE_UNISTD_H# include <unistd.h>#endif#include <sys/types.h>#include <fcntl.h>#include <errno.h>#ifndef __MINGW32__# include <sys/types.h># include <sys/socket.h># include <netinet/in.h># include <arpa/inet.h>#endif#ifdef __MINGW32__# include <winsock2.h># include <io.h>#endif#if HAVE_DIRECT_H# include <direct.h>#endif#ifdef __MINGW32__# define mkdir(path, mode) mkdir (path)#endif#include "libserveez.h"#include "gnutella.h"#include "nut-transfer.h"#include "nut-route.h"#include "nut-core.h"#include "nut-hostlist.h"#include "nut-request.h"/* * Default search patterns. */char *nut_search_patterns[] ={  "Puppe3000",  "Meret Becker",  NULL};/* * Default configuration hash for the gnutella spider. */nut_config_t nut_config = {  0,                   /* if set we do not listen on the above port cfg */  NUT_MAX_TTL,         /* maximum ttl for a gnutella packet */  NUT_TTL,             /* initial ttl for a gnutella packet */  NULL,                /* array of initial hosts */  NUT_GUID,            /* this servers GUID */  NULL,                /* routing table */  NULL,                /* connected hosts hash */  NULL,                /* default search pattern */  0,                   /* current search pattern index */  30,                  /* limit amount of search reply records */  NULL,                /* this servers created packets */  0,                   /* routing errors */  0,                   /* files within connected network */  0,                   /* file size (in KB) */  0,                   /* hosts within the connected network */  "/tmp",              /* where to store downloaded files */  "/tmp",              /* local search database path */  0,                   /* concurrent downloads */  4,                   /* maximum concurrent downloads */  28,                  /* connection speed (KBit/s) */  28,                  /* minimum connection speed for searching */  NULL,                /* file extensions */  NULL,                /* host catcher */  4,                   /* number of connections to keep up */  NULL,                /* force the local ip to this value */  0,                   /* calculated from `force_ip' */  0,                   /* force the local port to this value */  0,                   /* calculated from `force_port' */  NULL,                /* recent query hash */  NULL,                /* reply hash for routing push requests */  NULL,                /* push request hash */  NULL,                /* shared file array */  0,                   /* number of database files */  0,                   /* size of database in KB */  0,                   /* current number of uploads */  4,                   /* maximum number of uploads */  "gnutella-net",      /* configurable gnutella net url */  NULL,                /* detection string for the above value */};/* * Defining configuration file associations with key-value-pairs. */svz_key_value_pair_t nut_config_prototype[] = {  SVZ_REGISTER_STRARRAY ("hosts", nut_config.hosts, SVZ_ITEM_NOTDEFAULTABLE),  SVZ_REGISTER_STRARRAY ("search", nut_config.search, SVZ_ITEM_DEFAULTABLE),  SVZ_REGISTER_INT ("search-limit", nut_config.search_limit, 		    SVZ_ITEM_DEFAULTABLE),  SVZ_REGISTER_INT ("max-ttl", nut_config.max_ttl, SVZ_ITEM_DEFAULTABLE),  SVZ_REGISTER_INT ("ttl", nut_config.ttl, SVZ_ITEM_DEFAULTABLE),  SVZ_REGISTER_STR ("download-path", nut_config.save_path, 		    SVZ_ITEM_DEFAULTABLE),  SVZ_REGISTER_STR ("share-path", nut_config.share_path, SVZ_ITEM_DEFAULTABLE),  SVZ_REGISTER_INT ("max-downloads", nut_config.max_dnloads, 		    SVZ_ITEM_DEFAULTABLE),  SVZ_REGISTER_INT ("connection-speed", nut_config.speed, 		    SVZ_ITEM_DEFAULTABLE),  SVZ_REGISTER_INT ("min-speed", nut_config.min_speed, SVZ_ITEM_DEFAULTABLE),  SVZ_REGISTER_STRARRAY ("file-extensions", nut_config.extensions, 			 SVZ_ITEM_DEFAULTABLE),  SVZ_REGISTER_INT ("connections", nut_config.connections, 		    SVZ_ITEM_DEFAULTABLE),  SVZ_REGISTER_STR ("force-ip", nut_config.force_ip, SVZ_ITEM_DEFAULTABLE),  SVZ_REGISTER_INT ("force-port", nut_config.force_port, SVZ_ITEM_DEFAULTABLE),  SVZ_REGISTER_INT ("max-uploads", nut_config.max_uploads, 		    SVZ_ITEM_DEFAULTABLE),  SVZ_REGISTER_STR ("net-url", nut_config.net_url, SVZ_ITEM_DEFAULTABLE),  SVZ_REGISTER_END ()};/* * Definition of this server. */svz_servertype_t nut_server_definition ={  "gnutella spider version " NUT_VERSION, /* long description */  "nut",                                  /* instance description */  nut_global_init,                        /* global initializer */  nut_init,                               /* instance initializer */  nut_detect_proto,                       /* protocol detection */  nut_connect_socket,                     /* client connection callback */  nut_finalize,                           /* instance destructor */  nut_global_finalize,                    /* class destructor */  nut_info_client,                        /* server info callback */  nut_info_server,                        /* client info callback */  nut_server_notify,                      /* server timer routine */  NULL,                                   /* no handle request callback */  &nut_config,                            /* default configuration */  sizeof (nut_config),                    /* size of this configuration */  nut_config_prototype                    /* configuration items */};/* * The next three functions `nut_hash_keylen', `nut_hash_equals' and * `nut_hash_code' are the routing table hash callbacks to handle * GUIDs as keys instead of plain NULL terminated character strings. */static unsignednut_hash_keylen (char *id){  return NUT_GUID_SIZE;}static int nut_hash_equals (char *id1, char *id2){  return memcmp (id1, id2, NUT_GUID_SIZE);} static unsigned long nut_hash_code (char *id){  int n;  unsigned long code = 0;    for (n = 0; n < NUT_GUID_SIZE; n++)    {      code = (code << 2) ^ id[n];    }  return code;}/* * This is the default idle function for self connected gnutella hosts. * It simply returns an error if the socket was not connected in a * certain time. */intnut_connect_timeout (svz_socket_t *sock){  /*    * Did we try to connect to another host in order to download something,   * but failed within a certain time ? Then we need to send a push request   * to the host providing the original data.   */  if (sock->userflags & NUT_FLAG_DNLOAD)    {      nut_send_push (sock->cfg, sock->data);    }  return -1;}/* * The following routine tries to connect to a given gnutella host. * It returns -1 on errors and zero otherwise. */static intnut_connect_host (nut_config_t *cfg, char *host){  nut_host_t *client;  svz_socket_t *sock;  unsigned long ip;  unsigned short port;  int ret = -1;  /* try getting ip address and port */  if (nut_parse_addr (host, &ip, &port) == -1)    {      svz_log (LOG_WARNING, "nut: invalid host `%s'\n", host);      return ret;    }  /* get client from host catcher hash */  client = (nut_host_t *) svz_hash_get (cfg->net, host);  /* try to connect to this host */  if ((sock = svz_tcp_connect (ip, port)) != NULL)    {      svz_log (LOG_NOTICE, "nut: connecting %s:%u\n",	       svz_inet_ntoa (ip), ntohs (port));            sock->cfg = cfg;      sock->flags |= SOCK_FLAG_NOFLOOD;      sock->check_request = nut_detect_connect;      sock->idle_func = nut_connect_timeout;      sock->idle_counter = NUT_CONNECT_TIMEOUT;      svz_sock_printf (sock, NUT_CONNECT);      ret = 0;    }  /*    * If we could not connect then delete the client from host catcher    * hash and free the client structure.   */  if (client)    {      svz_hash_delete (cfg->net, host);      svz_free (client);    }  return ret;}/* * When establishing a new connection to another gnutella server this * functions pings it to get all further servers behind this server. */intnut_init_ping (svz_socket_t *sock){  nut_config_t *cfg = sock->cfg;  nut_client_t *client = sock->data;  nut_packet_t *pkt;  nut_header_t hdr;  svz_uint8_t *header;  /* create new gnutella header */  nut_calc_guid (hdr.id);  hdr.function = NUT_PING_REQ;  hdr.ttl = (svz_uint8_t) cfg->ttl;  hdr.hop = 0;  hdr.length = 0;  header = nut_put_header (&hdr);  /* put into sent packet hash */  pkt = svz_malloc (sizeof (nut_packet_t));  pkt->sock = sock;  pkt->sent = time (NULL);  svz_hash_put (cfg->packet, (char *) hdr.id, pkt);  /* update client and server statistics */  cfg->nodes -= client->nodes;  cfg->files -= client->files;  cfg->size -= client->size;  client->nodes = 0;  client->files = 0;  client->size = 0;  return svz_sock_write (sock, (char *) header, SIZEOF_NUT_HEADER);}/* * The gnutella servers global initializer. */intnut_global_init (svz_servertype_t *server){#ifdef __MINGW32__  /* try getting M$'s GUID creation routine */  if ((oleHandle = LoadLibrary ("ole32.dll")) != NULL)    {      CreateGuid = (CreateGuidProc) 	GetProcAddress (oleHandle, "CoCreateGuid");    }#endif /* __MINGW32__ */  /* initialize random seed */  srand (time (NULL));  /* initialize configuration default values */  nut_config.search = svz_config_strarray_create (nut_search_patterns);#if 0  /* Print structure sizes. */  printf ("header     : %d\n", sizeof (nut_header_t));  printf ("ping reply : %d\n", sizeof (nut_pong_t));  printf ("query      : %d\n", sizeof (nut_query_t));  printf ("record     : %d\n", sizeof (nut_record_t));  printf ("reply      : %d\n", sizeof (nut_reply_t));  printf ("push       : %d\n", sizeof (nut_push_t));  printf ("host       : %d\n", sizeof (nut_host_t));  printf ("client     : %d\n", sizeof (nut_client_t));  printf ("packet     : %d\n", sizeof (nut_packet_t));  printf ("push reply : %d\n", sizeof (nut_push_reply_t));  printf ("file       : %d\n", sizeof (nut_file_t));  printf ("config     : %d\n", sizeof (nut_config_t));  printf ("transfer   : %d\n", sizeof (nut_transfer_t));#endif  return 0;}/* * Gnutella spider server's instance initializer. */intnut_init (svz_server_t *server){  nut_config_t *cfg = server->cfg;  int n = 0;  struct stat buf;  char *p;  /* check the download and share path first */  if (strlen (cfg->save_path) == 0 || strlen (cfg->share_path) == 0)    {      svz_log (LOG_ERROR, "nut: no download/share path given\n");

⌨️ 快捷键说明

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