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

📄 packetfactory.cs

📁 P2P (peer to peer) file sharing program in C#. Supports Gnutella, Gnutella2, eDonkey, and OpenNap. w
💻 CS
📖 第 1 页 / 共 3 页
字号:
// PacketFactory.cs// Copyright (C) 2002 Matt Zyzik (www.FileScope.com)// // 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  USAusing System;using System.Net;using System.Text;using System.Collections;using ICSharpCode.SharpZipLib.Zip.Compression;namespace FileScope.Gnutella2{	/*	 * anything involving crafting packets for departure is done in PacketFactory.cs	 * reading packets should be totally OOP-based to allow clean & easy & flexible processing	 * when crafting packets, we care less about flexibility, and more about speed	 * there are static packets that are cached, packets that are part cached, and totally dynamic packets	 * all of these forms are covered and dealt with in this file	 */	/// <summary>	/// Encapsulate all outgoing G2 root packets.	/// Many subclasses representing packet types will inherit from this class.	/// </summary>	public abstract class OMessage	{		/// <summary>		/// Set the llen in the control byte.		/// </summary>		public static void Setllen(byte[] byt, int loc, int llen)		{			byt[loc] = 0x00;			byt[loc] |= (byte)(llen << 6);		}		/// <summary>		/// Set the nlen in the control byte.		/// </summary>		public static void Setnlen(byte[] byt, int loc, int nlen)		{			byt[loc] |= (byte)((nlen-1) << 3);		}		/// <summary>		/// Set the CF and BE flags in the control byte.		/// </summary>		public static void SetRest(byte[] byt, int loc, bool children)		{			if(children)				byt[loc] |= 0x04;			if(!Stats.Updated.le)				byt[loc] |= 0x02;		}		public abstract bool FillSendBuff(Sck sck, ref int buffIndex);		/// <summary>		/// If the OMessage subclass doesn't have a custom way of filling the send buffer, it should use this routine.		/// Hopefully the JITer will inline this function.		/// pckt is copied into sck.sendBuff		/// </summary>		public static bool StandardFill(Sck sck, ref int buffIndex, byte[] pckt)		{			int lenLeft = sck.sendBuff.Length - buffIndex;			if(pckt.Length > lenLeft)			{				if(buffIndex == 0)					sck.sendBuff = new byte[pckt.Length];				else					return false;			}			Array.Copy(pckt, 0, sck.sendBuff, buffIndex, pckt.Length);			buffIndex += pckt.Length;			return true;		}		/// <summary>
		/// If sameArrayRefIfTooBig is false, the contents of pckt will be copied into sck.sendBuff.
		/// If sameArrayRefIfTooBig is true, sck.sendBuff will be set to pckt.
		/// </summary>		public static bool StandardFill(Sck sck, ref int buffIndex, byte[] pckt, bool sameArrayRefIfTooBig)		{			int lenLeft = sck.sendBuff.Length - buffIndex;			if(pckt.Length > lenLeft)			{				if(buffIndex == 0)				{					if(sameArrayRefIfTooBig)					{						sck.sendBuff = pckt;						buffIndex += pckt.Length;						return true;					}					else						sck.sendBuff = new byte[pckt.Length];				}				else					return false;			}			Array.Copy(pckt, 0, sck.sendBuff, buffIndex, pckt.Length);			buffIndex += pckt.Length;			return true;		}		/// <summary>
		/// pckt will be copied into sck.sendBuff.
		/// </summary>		public static bool StandardFill(Sck sck, ref int buffIndex, byte[] pckt, int pcktLen)		{			int lenLeft = sck.sendBuff.Length - buffIndex;			if(pcktLen > lenLeft)			{				if(buffIndex == 0)					sck.sendBuff = new byte[pcktLen];				else					return false;			}			Array.Copy(pckt, 0, sck.sendBuff, buffIndex, pcktLen);			buffIndex += pcktLen;			return true;		}		/// <summary>		/// Just find out if the packet can fit.		/// </summary>		public static bool CanFit(Sck sck, ref int buffIndex, int len)		{			if(len > (sck.sendBuff.Length - buffIndex))			{				if(buffIndex == 0)					sck.sendBuff = new byte[len];				else					return false;			}			return true;		}	}	/// <summary>	/// Any OMessage aiming to be sent over a udp medium must implement this interface.	/// </summary>	public interface IUdpMessage	{		void SetupUdpPacket(OutgoingPacket op);	}	public class OHandshake : OMessage	{		public string handshake = "";		public override bool FillSendBuff(Sck sck, ref int buffIndex)		{			if(CanFit(sck, ref buffIndex, handshake.Length))			{				Encoding.ASCII.GetBytes(handshake, 0, handshake.Length, sck.sendBuff, buffIndex);				buffIndex += handshake.Length;				return true;			}			else				return false;		}	}	public class OKeepAlivePing : OMessage, IUdpMessage	{		public static byte[] pckt = null;		public void SetupUdpPacket(OutgoingPacket op)		{			CreatePacket();			byte[] udpPckt = new byte[pckt.Length+8];			Array.Copy(pckt, 0, udpPckt, 8, pckt.Length);			op.deflate = false;			//whatever byte[] op.pcktData is set to shouldn't be static because doing so is dangerous			op.pcktData = udpPckt;			op.acks = null;			op.parts = new BitArray(UDPSR.GetPartCount(udpPckt.Length-8), false);			op.len = udpPckt.Length-8;		}		public override bool FillSendBuff(Sck sck, ref int buffIndex)		{			CreatePacket();			return OMessage.StandardFill(sck, ref buffIndex, pckt);		}		void CreatePacket()		{			if(pckt == null)			{				pckt = new byte[1+2];				Setllen(pckt, 0, 0);				Setnlen(pckt, 0, 2);				SetRest(pckt, 0, false);				pckt[1] = (byte)'P';				pckt[2] = (byte)'I';			}		}	}	public class OUdpPing : OMessage	{		public static byte[] pckt = new byte[0];		public byte[] endpoint = new byte[6];		public override bool FillSendBuff(Sck sck, ref int buffIndex)		{			lock(pckt)			{				if(pckt.Length == 0)				{					pckt = new byte[1+1+2 + 1+1+3+6];					Setllen(pckt, 0, 1);					Setnlen(pckt, 0, 2);					SetRest(pckt, 0, true);					Endian.VarBytesFromInt(pckt, 1, pckt.Length-4, 1);					pckt[2] = (byte)'P';					pckt[3] = (byte)'I';					Setllen(pckt, 4, 1);					Setnlen(pckt, 4, 3);					SetRest(pckt, 4, false);					Endian.VarBytesFromInt(pckt, 5, 6, 1);					pckt[6] = (byte)'U';					pckt[7] = (byte)'D';					pckt[8] = (byte)'P';					//[endpoint]				}				Array.Copy(this.endpoint, 0, pckt, 9, 6);				return OMessage.StandardFill(sck, ref buffIndex, pckt);			}		}	}	public class OUdpPingRelay : OMessage	{		public static byte[] pckt = new byte[0];		public byte[] endpoint = new byte[6];		public override bool FillSendBuff(Sck sck, ref int buffIndex)		{			lock(pckt)			{				if(pckt.Length == 0)				{					pckt = new byte[1+1+2 + 1+1+3+6 + 1+5];					Setllen(pckt, 0, 1);					Setnlen(pckt, 0, 2);					SetRest(pckt, 0, true);					Endian.VarBytesFromInt(pckt, 1, pckt.Length-4, 1);					pckt[2] = (byte)'P';					pckt[3] = (byte)'I';					Setllen(pckt, 4, 1);					Setnlen(pckt, 4, 3);					SetRest(pckt, 4, false);					Endian.VarBytesFromInt(pckt, 5, 6, 1);					pckt[6] = (byte)'U';					pckt[7] = (byte)'D';					pckt[8] = (byte)'P';					//[endpoint]					Setllen(pckt, 15, 0);					Setnlen(pckt, 15, 5);					SetRest(pckt, 15, false);					pckt[16] = (byte)'R';					pckt[17] = (byte)'E';					pckt[18] = (byte)'L';					pckt[19] = (byte)'A';					pckt[20] = (byte)'Y';				}				Array.Copy(this.endpoint, 0, pckt, 9, 6);				return OMessage.StandardFill(sck, ref buffIndex, pckt);			}		}	}	public class OPong : OMessage, IUdpMessage	{		public static byte[] pckt = null;		public override bool FillSendBuff(Sck sck, ref int buffIndex)		{			CreatePacket();			return OMessage.StandardFill(sck, ref buffIndex, pckt);		}		public void SetupUdpPacket(OutgoingPacket op)		{			CreatePacket();			byte[] udpPckt = new byte[pckt.Length+8];			Array.Copy(pckt, 0, udpPckt, 8, pckt.Length);			op.deflate = false;			op.pcktData = udpPckt;			op.acks = null;			op.parts = new BitArray(UDPSR.GetPartCount(udpPckt.Length-8), false);			op.len = udpPckt.Length-8;		}		void CreatePacket()		{			if(pckt == null)			{				pckt = new byte[1+2];				Setllen(pckt, 0, 0);				Setnlen(pckt, 0, 2);				SetRest(pckt, 0, false);				pckt[1] = (byte)'P';				pckt[2] = (byte)'O';			}		}	}	public class OPongRelay : OMessage, IUdpMessage	{		public static byte[] pckt = null;		public override bool FillSendBuff(Sck sck, ref int buffIndex)		{			CreatePacket();			return OMessage.StandardFill(sck, ref buffIndex, pckt);		}		public void SetupUdpPacket(OutgoingPacket op)		{			CreatePacket();			byte[] udpPckt = new byte[pckt.Length+8];			Array.Copy(pckt, 0, udpPckt, 8, pckt.Length);			op.deflate = false;			op.pcktData = udpPckt;			op.acks = null;			op.parts = new BitArray(UDPSR.GetPartCount(udpPckt.Length-8), false);			op.len = udpPckt.Length-8;		}		void CreatePacket()		{			if(pckt == null)			{				pckt = new byte[1+1+2 + 1+5];				Setllen(pckt, 0, 1);				Setnlen(pckt, 0, 2);				SetRest(pckt, 0, true);				Endian.VarBytesFromInt(pckt, 1, pckt.Length-4, 1);				pckt[2] = (byte)'P';				pckt[3] = (byte)'O';				Setllen(pckt, 4, 0);				Setnlen(pckt, 4, 5);				SetRest(pckt, 4, false);				pckt[5] = (byte)'R';				pckt[6] = (byte)'E';				pckt[7] = (byte)'L';				pckt[8] = (byte)'A';				pckt[9] = (byte)'Y';			}		}	}	public class OLNI : OMessage	{		public static byte[] pckt = new byte[0];		public override bool FillSendBuff(Sck sck, ref int buffIndex)		{			lock(pckt)			{				if(pckt.Length == 0)				{					pckt = new byte[1+1+3 + 1+1+2+6 + 1+1+2+16 + 1+1+1+4 + 1+1+2+8 + 1+1+2+4];					Setllen(pckt, 0, 1);					Setnlen(pckt, 0, 3);					SetRest(pckt, 0, true);					//[len]					pckt[2] = (byte)'L';					pckt[3] = (byte)'N';					pckt[4] = (byte)'I';					Setllen(pckt, 5, 1);					Setnlen(pckt, 5, 2);					SetRest(pckt, 5, false);					Endian.VarBytesFromInt(pckt, 6, 6, 1);					pckt[7] = (byte)'N';					pckt[8] = (byte)'A';					//[endpoint]					Setllen(pckt, 15, 1);					Setnlen(pckt, 15, 2);					SetRest(pckt, 15, false);					Endian.VarBytesFromInt(pckt, 16, 16, 1);					pckt[17] = (byte)'G';					pckt[18] = (byte)'U';					Array.Copy(Stats.settings.myGUID, 0, pckt, 19, 16);					Setllen(pckt, 35, 1);					Setnlen(pckt, 35, 1);					SetRest(pckt, 35, false);					Endian.VarBytesFromInt(pckt, 36, 4, 1);					pckt[37] = (byte)'V';					pckt[38] = (byte)'F';					pckt[39] = (byte)'S';					pckt[40] = (byte)'C';					pckt[41] = (byte)'P';					Setllen(pckt, 42, 1);					Setnlen(pckt, 42, 2);					SetRest(pckt, 42, false);					Endian.VarBytesFromInt(pckt, 43, 8, 1);					pckt[44] = (byte)'L';					pckt[45] = (byte)'S';					//[library status (8)]					Setllen(pckt, 54, 1);					Setnlen(pckt, 54, 2);					SetRest(pckt, 54, false);					Endian.VarBytesFromInt(pckt, 55, 4, 1);					pckt[56] = (byte)'H';					pckt[57] = (byte)'S';					//[hub status (4)]				}				int pcktLen;				if(Stats.Updated.Gnutella2.ultrapeer)				{					pcktLen = pckt.Length;					//library status					uint filesTotal = (uint)Stats.Updated.filesShared;					uint kbTotal = (uint)Stats.Updated.kbShared;					foreach(Sck elsck in Sck.scks)						if(elsck != null)							if(elsck.mode == G2Mode.Leaf)							{								filesTotal += elsck.numFiles;								kbTotal += elsck.numKB;							}					Array.Copy(Endian.GetBytes(filesTotal, !Stats.Updated.le), 0, pckt, 46, 4);					Array.Copy(Endian.GetBytes(kbTotal, !Stats.Updated.le), 0, pckt, 50, 4);					//hub status					Array.Copy(Endian.GetBytes((ushort)ConnectionManager.leaves.Count, !Stats.Updated.le), 0, pckt, 58, 2);					Array.Copy(Endian.GetBytes((ushort)Stats.settings.gConnectionsToKeep, !Stats.Updated.le), 0, pckt, 60, 2);				}				else				{					pcktLen = pckt.Length - 8;					//library status					Array.Copy(Endian.GetBytes(Stats.Updated.filesShared, !Stats.Updated.le), 0, pckt, 46, 4);					Array.Copy(Endian.GetBytes(Stats.Updated.kbShared, !Stats.Updated.le), 0, pckt, 50, 4);				}				Endian.VarBytesFromInt(pckt, 1, pcktLen-5, 1);				Array.Copy(Endian.BigEndianIP(Stats.settings.ipAddress), 0, pckt, 9, 4);				Array.Copy(Endian.GetBytes((ushort)Stats.settings.port, !Stats.Updated.le), 0, pckt, 13, 2);				return OMessage.StandardFill(sck, ref buffIndex, pckt, pcktLen);			}		}	}	public class OKHL : OMessage	{		int chCount;		public override bool FillSendBuff(Sck sck, ref int buffIndex)		{			lock(HostCache.recentHubs)			{				int total = SizeTimestamp()+SizeNHs()+SizeCHs();				int numBytesLen = Endian.NumBytesFromInt(total);				if(!OMessage.CanFit(sck, ref buffIndex, 1+numBytesLen+3+total))					return false;				Setllen(sck.sendBuff, buffIndex, numBytesLen);				Setnlen(sck.sendBuff, buffIndex, 3);				SetRest(sck.sendBuff, buffIndex, true);				buffIndex++;				Endian.VarBytesFromInt(sck.sendBuff, buffIndex, total, numBytesLen);				buffIndex += numBytesLen;				sck.sendBuff[buffIndex] = (byte)'K';				buffIndex++;				sck.sendBuff[buffIndex] = (byte)'H';				buffIndex++;				sck.sendBuff[buffIndex] = (byte)'L';				buffIndex++;				//timestamp				Setllen(sck.sendBuff, buffIndex, 1);				Setnlen(sck.sendBuff, buffIndex, 2);				SetRest(sck.sendBuff, buffIndex, false);				buffIndex++;				Endian.VarBytesFromInt(sck.sendBuff, buffIndex, 4, 1);				buffIndex++;				sck.sendBuff[buffIndex] = (byte)'T';				buffIndex++;				sck.sendBuff[buffIndex] = (byte)'S';				buffIndex++;				Array.Copy(Endian.GetBytes(Stats.Updated.timestamp, !Stats.Updated.le), 0, sck.sendBuff, buffIndex, 4);				buffIndex += 4;				//neighboring hubs				for(int x = 0; x < ConnectionManager.ultrapeers.Count; x++)				{					Setllen(sck.sendBuff, buffIndex, 1);					Setnlen(sck.sendBuff, buffIndex, 2);					SetRest(sck.sendBuff, buffIndex, false);					buffIndex++;					Endian.VarBytesFromInt(sck.sendBuff, buffIndex, 6, 1);					buffIndex++;					sck.sendBuff[buffIndex] = (byte)'N';					buffIndex++;					sck.sendBuff[buffIndex] = (byte)'H';					buffIndex++;					Array.Copy(Endian.GetBytes(Sck.scks[((ConnectionManager.G2Host)ConnectionManager.ultrapeers.GetKey(x)).sockNum].remoteIPA), 0, sck.sendBuff, buffIndex, 4);					buffIndex += 4;					Array.Copy(Endian.GetBytes((ushort)Sck.scks[((ConnectionManager.G2Host)ConnectionManager.ultrapeers.GetKey(x)).sockNum].port, !Stats.Updated.le), 0, sck.sendBuff, buffIndex, 2);					buffIndex += 2;				}				//cached hubs				int pos = GUID.rand.Next(0, HostCache.recentHubs.Count);				while(this.chCount > 0)				{					Setllen(sck.sendBuff, buffIndex, 1);					Setnlen(sck.sendBuff, buffIndex, 2);					SetRest(sck.sendBuff, buffIndex, false);					buffIndex++;					Endian.VarBytesFromInt(sck.sendBuff, buffIndex, 10, 1);					buffIndex++;					sck.sendBuff[buffIndex] = (byte)'C';					buffIndex++;					sck.sendBuff[buffIndex] = (byte)'H';					buffIndex++;					Array.Copy(Endian.GetBytes((IPAddress)HostCache.recentHubs.GetKey(pos)), 0, sck.sendBuff, buffIndex, 4);					buffIndex += 4;					Array.Copy(Endian.GetBytes(((HubInfo)HostCache.recentHubs.GetByIndex(pos)).port, !Stats.Updated.le), 0, sck.sendBuff, buffIndex, 2);					buffIndex += 2;					Array.Copy(Endian.GetBytes(Stats.Updated.timestamp - ((HubInfo)HostCache.recentHubs.GetByIndex(pos)).timeKnown, !Stats.Updated.le), 0, sck.sendBuff, buffIndex, 4);					buffIndex += 4;					pos++;					if(pos == HostCache.recentHubs.Count)						pos = 0;					this.chCount--;				}				return true;			}		}		int SizeTimestamp()		{			return (1+1+2+4);		}		int SizeNHs()		{			int eachNH = 1+1+2+6;

⌨️ 快捷键说明

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