📄 packetfactory.cs
字号:
buffIndex++; Endian.VarBytesFromInt(bytarr, buffIndex, 6, 1); buffIndex++; bytarr[buffIndex] = (byte)'S'; buffIndex++; Array.Copy(Endian.GetBytes(ipep.Address), 0, bytarr, buffIndex, 4); buffIndex += 4; Array.Copy(Endian.GetBytes((ushort)ipep.Port, !Stats.Updated.le), 0, bytarr, buffIndex, 2); buffIndex += 2; } int pos = GUID.rand.Next(0, HostCache.recentHubs.Count); while(this.sCount2 > 0) { Setllen(bytarr, buffIndex, 1); Setnlen(bytarr, buffIndex, 1); SetRest(bytarr, buffIndex, false); buffIndex++; Endian.VarBytesFromInt(bytarr, buffIndex, 10, 1); buffIndex++; bytarr[buffIndex] = (byte)'S'; buffIndex++; Array.Copy(Endian.GetBytes((IPAddress)HostCache.recentHubs.GetKey(pos)), 0, bytarr, buffIndex, 4); buffIndex += 4; Array.Copy(Endian.GetBytes(((HubInfo)HostCache.recentHubs.GetByIndex(pos)).port, !Stats.Updated.le), 0, bytarr, buffIndex, 2); buffIndex += 2; Array.Copy(Endian.GetBytes(Stats.Updated.timestamp - ((HubInfo)HostCache.recentHubs.GetByIndex(pos)).timeKnown, !Stats.Updated.le), 0, bytarr, buffIndex, 4); buffIndex += 4; pos++; if(pos == HostCache.recentHubs.Count) pos = 0; this.sCount2--; } //null and guid bytarr[buffIndex] = 0x00; buffIndex++; Array.Copy(sGUID, gOffset, bytarr, buffIndex, 16); buffIndex += 16; } int SizeTimestamp() { return (1+1+2+4); } int SizeDs() { int eachD = 1+1+1+8; //we include the local hub (+1) this.dCount = ConnectionManager.ultrapeers.Count+1; return (eachD*this.dCount); } int SizeSs() { int eachS1 = 1+1+1+6; int eachS2 = 1+1+1+10; foreach(ConnectionManager.G2Host g2h in ConnectionManager.ultrapeers.Keys) if(Sck.scks[g2h.sockNum].neighbors.Count > 0) this.sCount1 += Sck.scks[g2h.sockNum].neighbors.Count; int num2 = this.sCount1 > 20 ? 6 : 10; this.sCount2 = GUID.rand.Next(3, num2); if(HostCache.recentHubs.Count < this.sCount2) this.sCount2 = HostCache.recentHubs.Count; return ((eachS1*this.sCount1) + (eachS2*this.sCount2)); } } public class OQH2 : OMessage, IUdpMessage { static byte[] pcktStaticPart = new byte[0]; public byte[] searchGUID; public int searchGUIDoffset; public Query.Interests interests = new Query.Interests(); public ArrayList matches; public void SetupUdpPacket(OutgoingPacket op) { //payload inside qh2 is static parts, dynamic parts, null, hop count + guid int payloadSize; byte[] wholepacket; int i; lock(pcktStaticPart) { payloadSize = this.GetSizeStaticParts() + this.GetSizeDynamicParts() + 1 + 17; wholepacket = new byte[8+this.GetSizeQH2Header(payloadSize)+payloadSize]; i = 8; FillQH2Header(wholepacket, ref i, payloadSize); Array.Copy(pcktStaticPart, 0, wholepacket, i, pcktStaticPart.Length); i += pcktStaticPart.Length; FillDynamicPart(wholepacket, ref i); FillRest(wholepacket, ref i); }#if DEBUG if(i != wholepacket.Length) System.Diagnostics.Debug.WriteLine("G2 oqh2 length problem");#endif op.deflate = false; op.pcktData = wholepacket; op.acks = null; op.parts = new BitArray(UDPSR.GetPartCount(wholepacket.Length-8), false); op.len = wholepacket.Length-8; } public override bool FillSendBuff(Sck sck, ref int buffIndex) { //payload inside qh2 is static parts, dynamic parts, null, hop count + guid int payloadSize; lock(pcktStaticPart) { payloadSize = this.GetSizeStaticParts() + this.GetSizeDynamicParts() + 1 + 17; if(!OMessage.CanFit(sck, ref buffIndex, this.GetSizeQH2Header(payloadSize)+payloadSize)) { if(buffIndex != 0) return false; else sck.sendBuff = new byte[this.GetSizeQH2Header(payloadSize)+payloadSize]; } FillQH2Header(sck.sendBuff, ref buffIndex, payloadSize); Array.Copy(pcktStaticPart, 0, sck.sendBuff, buffIndex, pcktStaticPart.Length); buffIndex += pcktStaticPart.Length; FillDynamicPart(sck.sendBuff, ref buffIndex); FillRest(sck.sendBuff, ref buffIndex); } return true; } public void BrowseHostData(out byte[] dataQH2s) { if(this.matches.Count == 0) { dataQH2s = new byte[0]; return; } //payload inside qh2 is static parts, dynamic parts, null, hop count + guid int payloadSize; int i; lock(pcktStaticPart) { payloadSize = this.GetSizeStaticParts() + this.GetSizeDynamicParts() + 1 + 17; dataQH2s = new byte[this.GetSizeQH2Header(payloadSize)+payloadSize]; i = 0; FillQH2Header(dataQH2s, ref i, payloadSize); Array.Copy(pcktStaticPart, 0, dataQH2s, i, pcktStaticPart.Length); i += pcktStaticPart.Length; FillDynamicPart(dataQH2s, ref i); FillRest(dataQH2s, ref i); } } void FillQH2Header(byte[] bytarr, ref int i, int payloadSize) { int numBytesLen = Endian.NumBytesFromInt(payloadSize); Setllen(bytarr, i, numBytesLen); Setnlen(bytarr, i, 3); SetRest(bytarr, i, true); i++; Endian.VarBytesFromInt(bytarr, i, payloadSize, numBytesLen); i += numBytesLen; bytarr[i] = (byte)'Q'; i++; bytarr[i] = (byte)'H'; i++; bytarr[i] = (byte)'2'; i++; } public static void ResetStaticPart() { lock(pcktStaticPart) pcktStaticPart = new byte[0]; } void FillStaticPart() { lock(pcktStaticPart) { int i = 0; //for neighboring hub scenario int sockNum = -1; if(!Stats.Updated.Gnutella2.ultrapeer && ConnectionManager.ultrapeers.Count > 0) { sockNum = ((ConnectionManager.G2Host)ConnectionManager.ultrapeers.GetKey(GUID.rand.Next(0, ConnectionManager.ultrapeers.Count))).sockNum; if(Sck.scks[sockNum].remoteIPA == null) sockNum = -1; } //guid, node address, neighboring hub, vendor code, browse host, chat tag if(sockNum != -1) pcktStaticPart = new byte[1+1+2+16 + 1+1+2+6 + 1+1+2+6 + 1+1+1+4 + 1+0+3+0 + 1+0+3+0]; else pcktStaticPart = new byte[1+1+2+16 + 1+1+2+6 + 0+0+0+0 + 1+1+1+4 + 1+0+3+0 + 1+0+3+0]; //GU Setllen(pcktStaticPart, i, 1); Setnlen(pcktStaticPart, i, 2); SetRest(pcktStaticPart, i, false); i++; Endian.VarBytesFromInt(pcktStaticPart, i, 16, 1); i++; pcktStaticPart[i] = (byte)'G'; i++; pcktStaticPart[i] = (byte)'U'; i++; Array.Copy(Stats.settings.myGUID, 0, pcktStaticPart, i, 16); i += 16; //NA Setllen(pcktStaticPart, i, 1); Setnlen(pcktStaticPart, i, 2); SetRest(pcktStaticPart, i, false); i++; Endian.VarBytesFromInt(pcktStaticPart, i, 6, 1); i++; pcktStaticPart[i] = (byte)'N'; i++; pcktStaticPart[i] = (byte)'A'; i++; Array.Copy(Endian.GetBytes(Stats.Updated.myIPA), 0, pcktStaticPart, i, 4); i += 4; Array.Copy(Endian.GetBytes((ushort)Stats.settings.port, !Stats.Updated.le), 0, pcktStaticPart, i, 2); i += 2; //NH if(sockNum != -1) { Setllen(pcktStaticPart, i, 1); Setnlen(pcktStaticPart, i, 2); SetRest(pcktStaticPart, i, false); i++; Endian.VarBytesFromInt(pcktStaticPart, i, 6, 1); i++; pcktStaticPart[i] = (byte)'N'; i++; pcktStaticPart[i] = (byte)'H'; i++; Array.Copy(Endian.GetBytes(Sck.scks[sockNum].remoteIPA), 0, pcktStaticPart, i, 4); i += 4; Array.Copy(Endian.GetBytes((ushort)Sck.scks[sockNum].port, !Stats.Updated.le), 0, pcktStaticPart, i, 2); i += 2; } //V Setllen(pcktStaticPart, i, 1); Setnlen(pcktStaticPart, i, 1); SetRest(pcktStaticPart, i, false); i++; Endian.VarBytesFromInt(pcktStaticPart, i, 4, 1); i++; pcktStaticPart[i] = (byte)'V'; i++; pcktStaticPart[i] = (byte)'F'; i++; pcktStaticPart[i] = (byte)'S'; i++; pcktStaticPart[i] = (byte)'C'; i++; pcktStaticPart[i] = (byte)'P'; i++; //BUP Setllen(pcktStaticPart, i, 0); Setnlen(pcktStaticPart, i, 3); SetRest(pcktStaticPart, i, false); i++; pcktStaticPart[i] = (byte)'B'; i++; pcktStaticPart[i] = (byte)'U'; i++; pcktStaticPart[i] = (byte)'P'; i++; //PCH Setllen(pcktStaticPart, i, 0); Setnlen(pcktStaticPart, i, 3); SetRest(pcktStaticPart, i, false); i++; pcktStaticPart[i] = (byte)'P'; i++; pcktStaticPart[i] = (byte)'C'; i++; pcktStaticPart[i] = (byte)'H'; i++; } } void FillDynamicPart(byte[] bytarr, ref int i) { foreach(FileObject fo in this.matches) { int numBytesLen = Endian.NumBytesFromInt(fo.tempOne); Setllen(bytarr, i, numBytesLen); Setnlen(bytarr, i, 1); SetRest(bytarr, i, true); i++; Endian.VarBytesFromInt(bytarr, i, fo.tempOne, numBytesLen); i += numBytesLen; bytarr[i] = (byte)'H'; i++; //urn Setllen(bytarr, i, 1); Setnlen(bytarr, i, 3); SetRest(bytarr, i, false); i++; Endian.VarBytesFromInt(bytarr, i, 25, 1); i++; bytarr[i] = (byte)'U'; i++; bytarr[i] = (byte)'R'; i++; bytarr[i] = (byte)'N'; i++; bytarr[i] = (byte)'s'; i++; bytarr[i] = (byte)'h'; i++; bytarr[i] = (byte)'a'; i++; bytarr[i] = (byte)'1'; i++; bytarr[i] = (byte)'\0'; i++; Array.Copy(fo.sha1bytes, 0, bytarr, i, 20); i += 20; //url if(interests.all || interests.locations) { Setllen(bytarr, i, 0); Setnlen(bytarr, i, 3); SetRest(bytarr, i, false); i++; bytarr[i] = (byte)'U'; i++; bytarr[i] = (byte)'R'; i++; bytarr[i] = (byte)'L'; i++; } if(interests.all || interests.descriptivenames) { //sz Setllen(bytarr, i, 1); Setnlen(bytarr, i, 2); SetRest(bytarr, i, false); i++; Endian.VarBytesFromInt(bytarr, i, 4, 1); i++; bytarr[i] = (byte)'S'; i++; bytarr[i] = (byte)'Z'; i++; Array.Copy(Endian.GetBytes(fo.b, !Stats.Updated.le), 0, bytarr, i, 4); i += 4; //dn int numBytesLen2 = Endian.NumBytesFromInt(fo.lcaseFileName.Length); Setllen(bytarr, i, numBytesLen2); Setnlen(bytarr, i, 2); SetRest(bytarr, i, false); i++; Endian.VarBytesFromInt(bytarr, i, fo.lcaseFileName.Length, numBytesLen2); i += numBytesLen2; bytarr[i] = (byte)'D'; i++; bytarr[i] = (byte)'N'; i++; Encoding.ASCII.GetBytes(fo.location, fo.location.Length-fo.lcaseFileName.Length, fo.lcaseFileName.Length, bytarr, i); i += fo.lcaseFileName.Length; } } } /// <summary> /// This will add on the null to signify the end of child packets. /// And it will also add the qh2 payload: hop count + guid. /// </summary> void FillRest(byte[] bytarr, ref int i) { bytarr[i] = 0x00; i++; bytarr[i] = 0x00; i++; Array.Copy(this.searchGUID, searchGUIDoffset, bytarr, i, 16); i += 16; } //five segments: query hit header, static parts, dynamic hits, null, hop count + guid int GetSizeQH2Header(int payloadSize) { return (1+Endian.NumBytesFromInt(payloadSize)+3); } int GetSizeStaticParts() { if(pcktStaticPart.Length == 0) FillStaticPart(); return pcktStaticPart.Length; } int GetSizeDynamicParts() { int total = 0; foreach(FileObject fo in this.matches) { //first deal with the /H/? children int payloadSize = 0; //urn... don't forget the null char that follows the string identifying the urn family payloadSize += (1+1+3+(5+20)); //url if(interests.all || interests.locations) payloadSize += (1+0+3+0); if(interests.all || interests.descriptivenames) { //sz payloadSize += (1+1+2+4); //dn payloadSize += (1+Endian.NumBytesFromInt(fo.lcaseFileName.Length)+2+fo.lcaseFileName.Length); } //store size fo.tempOne = payloadSize; //now header total += (1+Endian.NumBytesFromInt(payloadSize)+1+payloadSize); } return total; } } public class OPush : OMessage, IUdpMessage { static byte[] pckt = new byte[0]; public GUIDitem gitem; public static void SendPush(QueryHitObject qho) { if(qho.servIdent == null) return; if(!Stats.Updated.Gnutella2.ultrapeer && !Stats.Updated.udpIncoming && !Stats.Updated.everIncoming) return; OPush opush = new OPush(); opush.gitem = new GUIDitem(qho.servIdent); if((qho.hops == 0 || qho.hops == 1) && qho.sockWhereFrom != -1) Sck.scks[qho.sockWhereFrom].SendPacket(opush); else { if(qho.ipepNH != null) UDPSR.SendOutgoingPacket(opush, qho.ipepNH); } } public void SetupUdpPacket(OutgoingPacket op) { CreatePacket(); byte[] pcktCopy = new byte[8+pckt.Length]; Array.Copy(pckt, 0, pcktCopy, 8, pckt.Length); op.deflate = false; op.pcktData = pcktCopy; op.acks = null; op.parts = new BitArray(UDPSR.GetPartCount(pcktCopy.Length-8), false); op.len = pcktCopy.Length-8; } public override bool FillSendBuff(Sck sck, ref int buffIndex) { CreatePacket(); return OMessage.StandardFill(sck, ref buffIndex, pckt); } void CreatePacket() { if(pckt.Length != 0) { Array.Copy(this.gitem.gUiD, this.gitem.loc, pckt, 10, 16); return; } int i = 0; pckt = new byte[1+1+4 + 1+1+2+16 + 1+6]; Setllen(pckt, i, 1); Setnlen(pckt, i, 4); SetRest(pckt, i, true); i++; Endian.VarBytesFromInt(pckt, i, 27, 1); i++; pckt[i] = (byte)'P'; i++; pckt[i] = (byte)'U'; i++; pckt[i] = (byte)'S'; i++; pckt[i] = (byte)'H'; i++; //TO Setllen(pckt, i, 1); Setnlen(pckt, i, 2); SetRest(pckt, i, false); i++; Endian.VarBytesFromInt(pckt, i, 16, 1); i++; pckt[i] = (byte)'T'; i++; pckt[i] = (byte)'O'; i++; Array.Copy(this.gitem.gUiD, this.gitem.loc, pckt, i, 16); i += 16; pckt[i] = 0x00; i++; Array.Copy(Endian.GetBytes(Stats.Updated.myIPA), 0, pckt, i, 4); i += 4; Array.Copy(Endian.GetBytes((ushort)Stats.settings.port, !Stats.Updated.le), 0, pckt, i, 2); i += 2; } } /// <summary> /// If we're routing a packet, we just use this class to copy it verbatim. /// </summary> public class OCopy : OMessage, IUdpMessage { public byte[] header; public byte[] payload; public override bool FillSendBuff(Sck sck, ref int buffIndex) { if(CanFit(sck, ref buffIndex, header.Length+payload.Length)) { Array.Copy(header, 0, sck.sendBuff, buffIndex, header.Length); buffIndex += header.Length; Array.Copy(payload, 0, sck.sendBuff, buffIndex, payload.Length); buffIndex += payload.Length; return true; } else return false; } public void SetupUdpPacket(OutgoingPacket op) { byte[] pckt = new byte[header.Length+payload.Length]; Array.Copy(header, 0, pckt, 0, header.Length); Array.Copy(payload, 0, pckt, header.Length, payload.Length); op.deflate = false; op.pcktData = pckt; op.acks = null; op.parts = new BitArray(UDPSR.GetPartCount(pckt.Length-8), false); op.len = pckt.Length-8; } public void CreateHeader(string name, bool be, bool cf) { int llen = Endian.NumBytesFromInt(payload.Length); this.header = new byte[1+llen+name.Length]; this.header[0] = 0x00; this.header[0] |= (byte)(llen << 6); this.header[0] |= (byte)((name.Length-1) << 3); if(cf) this.header[0] |= 0x04; if(be) this.header[0] |= 0x02; Endian.VarBytesFromInt(this.header, 1, payload.Length, llen); Encoding.ASCII.GetBytes(name, 0, name.Length, this.header, 1+llen); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -