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

📄 gnutella.c

📁 linux下支持P2P的客户端程序,采用了Gnutella的方法,其中有实现Gnutella的具体源码,是一个基于p2p环境下的音乐共享软件,有助于对P2P的研究
💻 C
字号:
/*-*-linux-c-*-*//* *  gnewtellium - Newtella for Unix *  Copyright (C) 2001 Elias Athanasopoulos * *  This program 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 of the License, or *  (at your option) any later version. * *  This program 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 program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *//* These includes are needed in the specified   order by the BSD family. It maybe better to   add an #ifdef BSD or something here...*/#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdlib.h>#include <string.h>#include "newtella.h"#include "guid.h"#include "connection.h"#include "gnutella.h"#include "global.h"#include "file.h"#include "hosts.h"#include "uploads.h"gint gnutella_send_ping(struct newtella_connection *con, gint wake_up){	struct gnutella_header *header = newtella_malloc(sizeof *header);	gchar *data;       	guidget(header->guid);	header->f      = GNUTELLA_INIT;	if (wake_up)		header->ttl = 1;	else		header->ttl = GNUTELLA_PING_TTL;	header->hops   = 0;	header->length = 0;	data = newtella_malloc(GN_HEADER_SIZE);	GNUTELLA_HDR_ATTACH(data, header)	con_send_packet(con, data, GN_HEADER_SIZE, 0);		newtella_free(header);	newtella_free(data);	return 1;}gint gnutella_send_pong(struct newtella_connection *con, gchar *guid, guint8 ttl){	struct gnutella_header *header;	struct gnutella_pong_header *gpong;	guint32 pack_size = 0;	gchar *data;	header = newtella_malloc(sizeof *header);	gpong  = newtella_malloc(sizeof *gpong);       	guidcpy(header->guid, guid);	header->f      = GNUTELLA_INITRESPONSE;	header->hops   = 0;	header->ttl    = ttl;	header->length = GN_PONG_SIZE;	gpong->host_ip          = g_htonl(gl_my_host_info->ip);	gpong->host_port        = gl_my_host_info->port;	gpong->file_count       = gl_my_host_info->file_count;	gpong->files_total_size = gl_my_host_info->files_total_size;	pack_size = GN_HEADER_SIZE + header->length;	data = newtella_malloc(pack_size);	GNUTELLA_HDR_ATTACH(data, header)		data += GN_HEADER_SIZE;	memcpy(data, &(gpong->host_port), 2);	memcpy(data+2, &(gpong->host_ip), 4);	memcpy(data+6, &(gpong->file_count), 4);	memcpy(data+10, &(gpong->files_total_size), 4);	data -= GN_HEADER_SIZE;        con_send_packet(con, data, pack_size, 1);       		newtella_free(header);	newtella_free(gpong);	newtella_free(data);	return 1;}gint gnutella_send_cached_host(struct newtella_connection *con, struct host_info *host){	struct gnutella_header *header;	struct gnutella_pong_header *gpong;	gchar *data;	header = newtella_malloc(sizeof *header);	gpong = newtella_malloc(sizeof *gpong);       	guidget(header->guid);	header->f      = GNUTELLA_INITRESPONSE;	header->hops   = 0;	header->ttl    = 1;	header->length = GN_PONG_SIZE;	gpong->host_ip          = g_htonl(host->ip);	gpong->host_port        = host->port;	gpong->file_count       = host->file_count;	gpong->files_total_size = host->files_total_size;	data = newtella_malloc(GN_HEADER_SIZE + header->length);	GNUTELLA_HDR_ATTACH(data, header)		data += GN_HEADER_SIZE;	memcpy(data, &(gpong->host_port), 2);	memcpy(data+2, &(gpong->host_ip), 4);	memcpy(data+6, &(gpong->file_count), 4);	memcpy(data+10, &(gpong->files_total_size), 4);	data -= GN_HEADER_SIZE; 	con_send_packet(con, data, GN_HEADER_SIZE + header->length, 0);       		newtella_free(header);	newtella_free(gpong);	newtella_free(data);	return 1;}gint gnutella_send_query(struct squery *query, struct newtella_connection *con, gint broadcast){	struct  gnutella_header *header;	struct  gnutella_query_header *query_header;	guint32 pack_size = 0;	gchar  *data;        query_header = newtella_malloc(sizeof *query_header);	query_header->min_speed = 0;	header = newtella_malloc(sizeof *header);	guidcpy(header->guid, query->guid);	header->f      = GNUTELLA_SEARCH;	header->ttl    = GNUTELLA_SEARCH_TTL;	header->hops   = 0;	header->length = GN_QUERY_SIZE + strlen(query->keyword) + 1;		pack_size = GN_HEADER_SIZE + header->length;	data = newtella_malloc(pack_size);	GNUTELLA_HDR_ATTACH(data, header)	data += GN_HEADER_SIZE;	memcpy(data, &(query_header->name), GN_QUERY_SIZE);	data += GN_QUERY_SIZE;	strcpy(data, query->keyword);	data -= GN_HEADER_SIZE + GN_QUERY_SIZE;	if (broadcast)		con_send_to_all(data, pack_size, 0);	else		con_send_packet(con, data, pack_size, 0); 			newtella_free(header);	newtella_free(query_header);	newtella_free(data);	return 1;}gint gnutella_send_query_response(struct newtella_connection *con, GList *found_hits, gchar *guid){	GList *iter;	struct gnutella_hits *ghits = newtella_malloc(sizeof *ghits);	struct gnutella_header *header = newtella_malloc(sizeof *header);	struct file_entry *fe;       	gchar *data, *p;	gchar open_data_byte = 0;		gint i = 0, str_offs = 0, packet_size = 0;       	ghits->n    = g_list_length(found_hits);	ghits->port = gl_my_host_info->port;		if (host_is_private(gl_my_host_info->ip, gl_my_host_info->port))		ghits->ip = g_htonl(gl_options->local_ip);	else		ghits->ip = g_htonl(gl_my_host_info->ip);	ghits->speed = gl_options->con_speed;	guidcpy(header->guid, guid);	header->f    = GNUTELLA_SEARCHRESPONSE;	header->ttl  = GNUTELLA_SEARCH_TTL;	header->hops = 0;	/* find out the size of the packet 	 * we have to add: 	 * - gnutella header	 * - hits header	 * - (hit header) x number of hits	 * - size of each returned file name + 2 for \0\0	 * - extended QHD: 1 length byte + 2 status bytes + 4 bytes for the vendor code	 * - our guid (last 16 bytes)	 */	packet_size = GN_HEADER_SIZE + GN_HITS_SIZE + 		ghits->n*GN_HIT_SIZE + GN_EXTENDED_QHD_SIZE + 16;	iter = g_list_first(found_hits);	while (iter) {		fe = (struct file_entry*)iter->data;		/* add size of the file name to packet size */		packet_size += (strlen(fe->name) + 2);				iter = g_list_next(iter);	}        /* now we know exactly how many bytes 	   are needed for the new packet */	data = newtella_malloc(packet_size);	/* copy standard header */	GNUTELLA_HDR_ATTACH(data, header)	/* copy standard gnutella hits header */	GNUTELLA_HITS_ATTACH((data+GN_HEADER_SIZE), ghits)	/* copy each hit */	iter = g_list_first(found_hits);	while (iter) {		fe = (struct file_entry*)iter->data;		p = data+str_offs+GN_HEADER_SIZE+GN_HITS_SIZE+GN_HIT_SIZE*i;		memcpy(p, &(fe->index), 4);		memcpy(p+4, &(fe->size), 4);		memcpy(p+8, fe->name, strlen(fe->name));		memcpy(p+8+strlen(fe->name), "\0\0", 2);			i++;		str_offs += (strlen(fe->name)+2);		iter = g_list_next(iter);	}	/* attach the QHD data */	p = data+packet_size - 16 - GN_EXTENDED_QHD_SIZE;	i = upload_active_con();	if (i == gl_options->max_uploads)		/* busy */		open_data_byte |= QHD_BUSY_BIT_MASK;	if (host_is_private(gl_my_host_info->ip, gl_my_host_info->port)) 		/* push */		open_data_byte |= QHD_PUSH_BIT_MASK;		/* vendor */	memcpy(p, "GNEW", 4);	i = QHD_OD_SIZE;	memcpy(p+4, &i, 1);	memcpy(p+5, &open_data_byte, 1);	memcpy(p+6, &open_data_byte, 1);	/* copy guid to the last 16 bytes */	guidcpy(data+packet_size-16, gl_options->gl_guid);	header->length = packet_size - GN_HEADER_SIZE;		/* adjust header length */	memcpy(data+19, &(header->length), 4);	con_send_packet(con, data, header->length+GN_HEADER_SIZE, 1);	newtella_free(header);	newtella_free(ghits);	newtella_free(data);	return 1;}gint gnutella_send_push(struct newtella_connection *dcon){	struct gnutella_header *header = newtella_malloc(sizeof *header);	struct gnutella_push   *gpush  = newtella_malloc(sizeof *gpush);	char *data;	guidget(header->guid);	header->f      = GNUTELLA_PUSHREQUEST;	header->ttl    = GNUTELLA_SEARCH_TTL;	header->hops   = 0;	header->length = GN_PUSH_SIZE;	guidcpy(gpush->guid, dcon->fi->guid);	gpush->index = dcon->fi->index;	gpush->ip    = g_htonl(gl_options->local_ip);	gpush->port  = dcon->port;	data = newtella_malloc(GN_HEADER_SIZE+GN_PUSH_SIZE);	GNUTELLA_HDR_ATTACH(data, header)	data += GN_HEADER_SIZE;	memcpy(data, &(gpush->guid), 16);	memcpy(data+16, &(gpush->index), 4);	memcpy(data+20, &(gpush->ip), 4);       	memcpy(data+24, &(gpush->port), 2);		data -= GN_HEADER_SIZE;      	con_send_to_all(data, GN_HEADER_SIZE+GN_PUSH_SIZE, 0);	newtella_free(header);	newtella_free(gpush);	newtella_free(data);	return 1;}/* various help functions */gchar *translate_vendor_id(gchar *vid){	if (!strncmp(vid, "GNEW", 4))		return "Gnewtellium";	if (!strncmp(vid, "BEAR", 4))		return "BearShare";	if (!strncmp(vid, "LIME", 4))		return "LimeWire";	if (!strncmp(vid, "TOAD", 4))		return "ToadNode";	if (!strncmp(vid, "GNOT", 4))		return "Gnotella";	if (!strncmp(vid, "MACT", 4))		return "Mactella";	if (!strncmp(vid, "GNUC", 4))		return "Gnucleus";	if (!strncmp(vid, "GNUT", 4))		return "Gnut";	if (!strncmp(vid, "GTKG", 4))		return "Gtk-Gnutella";	if (!strncmp(vid, "NAPS", 4))		return "NapShare";	if (!strncmp(vid, "OCFG", 4))		return "OpenCola";	if (!strncmp(vid, "HSLG", 4))		return "Hagelslag";	if (!strncmp(vid, "CULT", 4))		return "Cultiv8r";	if (!strncmp(vid, "PHEX", 4))		return "Phex";	if (!strncmp(vid, "XOLO", 4))		return "Xolox";	if (!strncmp(vid, "MNAP", 4))		return "MyNapster";	if (!strncmp(vid, "SNUT", 4))		return "SwapNut";	if (!strncmp(vid, "QTEL", 4))		return "QTella";	else//		return vid;		return "Unknown";	}gint rate_result_set(gint rs, gchar *open_data_byte, gchar *vendor){	struct file_found *found;	GList *iter;	gint busy;	gint push;	if (((open_data_byte[1] & 4) == 4) && ((open_data_byte[2] & 4) == 4)) 		busy = 1;	else		busy = 0;       	if (((open_data_byte[1] & 1) == 1) && ((open_data_byte[2] & 1) == 1)) 		push = 1;  	else		push = 0;	iter = g_list_nth(gl_results, rs);		while (iter) {		found = iter->data;				found->busy = busy;		if (!found->push && push)			found->push = push;		memcpy(found->servent, vendor, 4);		iter = g_list_next(iter);	}	return 1;}/* debug */void gnutella_hdr_dump(struct gnutella_header *hdr){	guiddump(hdr->guid);	g_print("f: %d ttl: %d hops %d len: %d\n",		hdr->f, hdr->ttl, hdr->hops, hdr->length);}

⌨️ 快捷键说明

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