?? gnutella.c
字號:
/* * 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 + -