📄 messages.cs
字号:
lock(HostCache.recentHubs) Sck.scks[root.sockNum].neighbors.Add(new IPEndPoint(Endian.GetIPAddress(root.inPayload, offset), Endian.ToUInt16(root.inPayload, offset+4, root.be))); } public override Child ChildType(ref string name) { if(name == "GU") return new GuIdent(); else if(name == "V") return new VendorCode(); else if(name == "LS") return new LibraryStats(); else if(name == "HS") return new HubStatus(); else return new UnknownChild(ref name); } public class GuIdent : Child { public override void Process(int offset, int len) { // } } public class VendorCode : Child { public override void Process(int offset, int len) { // } } public class LibraryStats : Child { public override void Process(int offset, int len) { // } } public class HubStatus : Child { public override void Process(int offset, int len) { // } } } public class CachedHub : Child { public IPAddress ipa; public ushort port; public int timeStamp; public override void Process(int offset, int len) { if(len == 10) { this.ipa = Endian.GetIPAddress(root.inPayload, offset); this.port = Endian.ToUInt16(root.inPayload, offset+4, root.be); this.timeStamp = Endian.ToInt32(root.inPayload, offset+len-4, root.be); } else Utils.Diag("G2 KHL/CH wrong length: " + len.ToString()); } public override Child ChildType(ref string name) { if(name == "GU") return new GuIdent(); else if(name == "V") return new VendorCode(); else if(name == "LS") return new LibraryStats(); else if(name == "HS") return new HubStatus(); else return new UnknownChild(ref name); } public class GuIdent : Child { public override void Process(int offset, int len) { // } } public class VendorCode : Child { public override void Process(int offset, int len) { // } } public class LibraryStats : Child { public override void Process(int offset, int len) { // } } public class HubStatus : Child { public override void Process(int offset, int len) { // } } } } public class Push : Message { public int offsetGUID = -1; public override void Process(int offset, int len) { Child child = this.children; while(child != null) { child.Read(child.offset); child = child.nextChild; } if(offsetGUID != -1) { if(GUID.Compare(root.inPayload, offsetGUID, Stats.settings.myGUID, 0)) { //this push was for us goto push_for_us; } else if(Stats.Updated.Gnutella2.ultrapeer) { //maybe we can route this push GUIDitem gitem = new GUIDitem(root.inPayload, offsetGUID); Router.RouteEntry re; lock(Router.htRoutes) { if(Router.htRoutes.ContainsKey(gitem)) re = (Router.RouteEntry)Router.htRoutes[gitem];#if DEBUG else { Utils.Diag("G2 Push no route found"); return; }#else else return;#endif } OCopy ocopy = new OCopy(); ocopy.payload = root.inPayload; ocopy.CreateHeader("PUSH", root.be, root.cf); Router.RoutePacket(ocopy, re); } } if(this.children == null) goto push_for_us; return; push_for_us: if(len == 6) { IPAddress ipa = Endian.GetIPAddress(root.inPayload, offset); int port = Endian.ToUInt16(root.inPayload, offset+4, root.be); //the -5 indicates it's a G2, not G1 upload UploadManager.Outgoing(-5, ipa.ToString(), port); } } public override Child ChildType(ref string name) { if(name == "TO") return new To(); else return new UnknownChild(ref name); } public class To : Child { public override void Process(int offset, int len) { if(len == 16) ((Push)this.root).offsetGUID = offset; else System.Diagnostics.Debug.WriteLine("g2 Push guid is of wrong length: " + len.ToString()); } } } public class QueryHashTable : Message { public override void Process(int offset, int len) { if(root.inPayload[offset] == 0x00) { lock(Sck.scks[root.sockNum]) { if(len != 6) System.Diagnostics.Debug.WriteLine("g2 qht wrong size: " + len.ToString()); Sck.scks[root.sockNum].inQHT = new BitArray(Endian.ToInt32(root.inPayload, offset+1, root.be), true); } } else if(root.inPayload[offset] == 0x01) { lock(Sck.scks[root.sockNum]) { //first fragment? if(root.inPayload[offset+1] == 0x01) { Sck.scks[root.sockNum].inRawQHTindex = 0; Sck.scks[root.sockNum].inRawQHT = new byte[(len-5) * (int)root.inPayload[offset+2]]; } Array.Copy(root.inPayload, offset+5, Sck.scks[root.sockNum].inRawQHT, Sck.scks[root.sockNum].inRawQHTindex, len-5); Sck.scks[root.sockNum].inRawQHTindex += (len-5); //last fragment? if(root.inPayload[offset+1] == root.inPayload[offset+2]) { BitArray baPatch; bool compressed = (root.inPayload[offset+3] == 0x01); if(!compressed) baPatch = new BitArray(Sck.scks[root.sockNum].inRawQHT); else { byte[] unCompressed = new byte[Sck.scks[root.sockNum].inQHT.Length / 8]; ICSharpCode.SharpZipLib.Zip.Compression.Inflater ifer = new ICSharpCode.SharpZipLib.Zip.Compression.Inflater(); ifer.SetInput(Sck.scks[root.sockNum].inRawQHT, 0, Sck.scks[root.sockNum].inRawQHTindex); ifer.Inflate(unCompressed); baPatch = new BitArray(unCompressed); } //apply the patch Sck.scks[root.sockNum].inQHT.Xor(baPatch); } } } else System.Diagnostics.Debug.WriteLine("q2 qht wrong command: " + root.inPayload[offset].ToString()); } } public class QueryKeyRequest : Message { public override void Process(int offset, int len) { if(root.sockNum != -1) { System.Diagnostics.Debug.WriteLine("g2 qkr over tcp?"); return; } if(!Stats.Updated.Gnutella2.ultrapeer) return; Child child = this.children; while(child != null) { child.Read(child.offset); child = child.nextChild; } } public override Child ChildType(ref string name) { if(name == "RNA") return new RNodeAddress(); else return new UnknownChild(ref name); } public class RNodeAddress : Child { public override void Process(int offset, int len) { if(len == 6) { IPEndPoint ipep = new IPEndPoint(Endian.GetIPAddress(root.inPayload, offset), Endian.ToUInt16(root.inPayload, offset+4, root.be)); OQKA oqka = new OQKA(); oqka.queryKey = GUID.rand.Next(); oqka.qk = true; oqka.sna = ipep.Address; HostCache.SentQueryKey(oqka.queryKey, ipep); UDPSR.SendOutgoingPacket(oqka, ipep); } else System.Diagnostics.Debug.WriteLine("RNodeAddress invalid len: " + len.ToString()); } } } public class QueryKeyAnswer : Message { public int queryKey = -1; public bool qk = false; public IPAddress sna = null; public IPAddress qna = null; public override void Process(int offset, int len) { Child child = this.children; while(child != null) { child.Read(child.offset); child = child.nextChild; } try { if(!qk) {#if DEBUG System.Diagnostics.Debug.WriteLine("g2 no query key received... perhaps our query key is no longer valid");#endif HubInfo hi; lock(HostCache.hubCache) { if(qna == null) hi = (HubInfo)HostCache.hubCache[root.ipep.Address]; else hi = (HubInfo)HostCache.hubCache[qna]; } hi.timeKnown = 0; hi.mhi.qk = false; hi.mhi.queryKeyedHub = null; } else { //System.Diagnostics.Debug.WriteLine("query key present"); HubInfo hi; lock(HostCache.hubCache) { if(qna == null) { hi = (HubInfo)HostCache.hubCache[root.ipep.Address]; hi.mhi.queryKeyedHub = null; } else { hi = (HubInfo)HostCache.hubCache[qna]; hi.mhi.queryKeyedHub = Sck.scks[root.sockNum].remoteIPA; } } hi.timeKnown = 0; hi.mhi.queryKey = this.queryKey; hi.mhi.qk = true; //we need to use this hub for either a normal query or a requery from a download int chance; int val = 1; if(ReQuery.g2requeried) { val = 2; ReQuery.g2requeried = false; } chance = GUID.rand.Next(0, val); if(chance == 1 || (Search.activeSearches.Count == 0 && val == 2)) { if(qna == null) ReQuery.Gnutella2NewHub(root.ipep.Address, hi); else ReQuery.Gnutella2NewHub(qna, hi); } else if(chance == 0) { lock(Search.activeSearches) { if(Search.activeSearches.Count > 0) { int which = GUID.rand.Next(0, Search.activeSearches.Count); if(qna == null) ((Search)Search.activeSearches[which]).NewHub(root.ipep.Address, hi); else ((Search)Search.activeSearches[which]).NewHub(qna, hi); } } } } } catch(Exception e) { System.Diagnostics.Debug.WriteLine("g2 QKA: " + e.Message); System.Diagnostics.Debug.WriteLine(e.StackTrace); } try { //routing? if(Stats.Updated.Gnutella2.ultrapeer && !this.sna.Equals(Stats.Updated.myIPA) && this.qna == null) { lock(HostCache.recentHubs) { if(ConnectionManager.htDirects.ContainsKey(this.sna)) { int sockNum = ((ConnectionManager.G2Host)ConnectionManager.htDirects[this.sna]).sockNum; OQKA oqka = new OQKA(); oqka.qna = root.ipep.Address; oqka.sna = this.sna; oqka.queryKey = this.queryKey; oqka.qk = this.qk; Sck.scks[sockNum].SendPacket(oqka); } } } } catch(Exception e) { System.Diagnostics.Debug.WriteLine("g2 QKA2: " + e.Message); System.Diagnostics.Debug.WriteLine(e.StackTrace); } } public override Child ChildType(ref string name) { if(name == "QK") return new QueryKey(); else if(name == "SNA") return new SNodeAddress(); else if(name == "QNA") return new QNodeAddress(); else return new UnknownChild(ref name); } public class QueryKey : Child { public override void Process(int offset, int len) { if(len >= 4) { ((QueryKeyAnswer)this.root).queryKey = Endian.ToInt32(root.inPayload, offset, root.be); ((QueryKeyAnswer)this.root).qk = true; } } } public class SNodeAddress : Child { public override void Process(int offset, int len) { if(len == 4 || len == 6) ((QueryKeyAnswer)this.root).sna = Endian.GetIPAddress(root.inPayload, offset); else Utils.Diag("QKA SNA wrong size"); } } public class QNodeAddress : Child { public override void Process(int offset, int len) { if(len == 4 || len == 6) ((QueryKeyAnswer)this.root).qna = Endian.GetIPAddress(root.inPayload, offset); else Utils.Diag("QKA QNA wrong size"); } } } public class Query : Message { //descriptive name public string dn = ""; //udp or tcp public bool fromUdp = false; //return address and query key public IPEndPoint ipepReturn = null; public int queryKey; //urn linked list public URNinfo urns = null; public class URNinfo { /// <summary>
/// range in root.inPayload... not this.fullurn
/// </summary> public int loc, len; //full urn in string form (ex. urn:sha1:WIXYJFVJMIWNMUWPRPBGUTODIV52RMJA) public string fullurn; //next URNinfo object public URNinfo next = null; } //size restrictions: public bool sizeRestrict = false; public uint minSize; public uint maxSize; //interests; null means everything public string[] interests = null; public override void Process(int offset, int len) { if(len != 16) { System.Diagnostics.Debug.WriteLine("bad g2 query payload length: " + len.ToString()); throw new Exception("bad g2 query payload length"); } if(root.ipep != null) this.fromUdp = true; //whether or not we're an ultrapeer, it's necessary to make sure this isn't a duplicate query GUIDitem gitem = new GUIDitem(root.inPayload, offset); Router.RouteEntry re; lock(Router.htRoutes) { //query duplicate? if(Router.htRoutes.ContainsKey(gitem)) return; re = new Router.RouteEntry(); re.gitem_key = gitem; if(this.fromUdp) { //this may change if a udp child is found re.ipep = root.ipep; re.sckNum = -1; } else { re.ipep = null; re.sckNum = root.sockNum; } re.timeLeft = 120; Router.htRoutes.Add(gitem, re); } Child child = this.children; while(child != null) { child.Read(child.offset); child = child.nextChild; } //honor udp packet if present if(this.ipepReturn != null) { re.ipep = this.ipepReturn; re.sckNum = -1; } //check query key bool sendACK = false; if(Stats.Updated.Gnutella2.ultrapeer && this.ipepReturn != null && this.fromUdp) { if(!HostCache.QueryKeyOK(this.ipepReturn, this.queryKey)) {#if DEBUG Utils.Diag("someone's g2 key wasn't valid");#endif //we need to notify the host that the query key is invalid OQKA oqka = new OQKA(); oqka.sna = this.ipep.Address; oqka.qk = false; oqka.qna = null; UDPSR.SendOutgoingPacket(oqka, this.ipepReturn); return; } else sendACK = true; } if(Stats.Updated.Gnutella2.ultrapeer && !this.fromUdp) if(Sck.scks[this.sockNum].mode == G2Mode.Leaf) sendACK = true; if(sendACK) { //send qa either by udp or tcp OQA oqa = new OQA(); oqa.sGUID = root.inPayload; oqa.gOffset = offset; oqa.tcp = (this.sockNum != -1); if(oqa.tcp) Sck.scks[this.sockNum].SendPacket(oqa); else { if(this.ipepReturn != null)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -