📄 messages.cs
字号:
UDPSR.SendOutgoingPacket(oqa, this.ipepReturn); else UDPSR.SendOutgoingPacket(oqa, root.ipep); } }#if DEBUG//System.Diagnostics.Debug.WriteLine("dn----> " + dn);#endif if(dn.Length > 0) GUIBridge.QueryG2(ref dn); G2Word g2words = null; //check if we might have it if(dn.Length > 0 || urns != null) { ArrayList matches = null; if(this.urns != null) { bool hashQHTmatch = false; URNinfo curURN = this.urns; lock(QueryRouteTable.ourQHT) { while(curURN != null) { if(QueryRouteTable.ourQHT[Hashing.Hash(ref curURN.fullurn, curURN.fullurn.Length, 20)] == false) { hashQHTmatch = true; break; } else curURN = curURN.next; } } if(!hashQHTmatch) goto noLocalQHTMatch; //if passed qht check, check files lock(Stats.fileList) { foreach(FileObject fi in Stats.fileList) { bool match = false; curURN = this.urns; while(curURN != null) { if(curURN.fullurn.Substring(0, 8) == "urn:sha1") { if(Utils.SameArray(root.inPayload, curURN.loc, curURN.len, fi.sha1bytes, 0, fi.sha1bytes.Length)) { match = true; break; } } else if(curURN.fullurn.Substring(0, 8) == "urn:ed2k") { if(Utils.SameArray(root.inPayload, curURN.loc, curURN.len, fi.md4, 0, fi.md4.Length)) { match = true; break; } } curURN = curURN.next; } if(match && sizeRestrict) { if(fi.b < minSize || fi.b > maxSize) match = false; } if(match && fi.sha1.Length > 0) { if(matches == null) matches = new ArrayList(); matches.Add(fi); } } } } else { G2Word g2wFirst = Keywords.GetG2Keywords(ref dn); g2words = g2wFirst; if(g2wFirst != null) { //first check our hash table G2Word g2wCurr1 = g2wFirst; lock(QueryRouteTable.ourQHT) { while(g2wCurr1 != null) { if(!g2wCurr1.negative) { g2wCurr1.subwords = g2wCurr1.word.Split(new char[] {' ', ','}, 15); for(int z = 0; z < g2wCurr1.subwords.Length; z++) //true means empty if(QueryRouteTable.ourQHT[Hashing.Hash(ref g2wCurr1.subwords[z], g2wCurr1.subwords[z].Length, 20)] == true) goto noLocalQHTMatch; } g2wCurr1 = g2wCurr1.next; } } //if passed qht check, check files lock(Stats.fileList) { foreach(FileObject fi in Stats.fileList) { G2Word g2wCurrent = g2wFirst; bool match = true; while(g2wCurrent != null) { if(g2wCurrent.negative) { if(fi.lcaseFileName.IndexOf(g2wCurrent.word) != -1) { match = false; break; } } else { if(fi.lcaseFileName.IndexOf(g2wCurrent.word) == -1) { match = false; break; } } g2wCurrent = g2wCurrent.next; } if(match && sizeRestrict) { if(fi.b < minSize || fi.b > maxSize) match = false; } if(match && fi.sha1.Length > 0) { if(matches == null) matches = new ArrayList(); matches.Add(fi); } } } } } if(matches != null) { //send query hit OQH2 oqh2 = new OQH2(); oqh2.searchGUID = root.inPayload; oqh2.searchGUIDoffset = offset; if(this.interests == null) oqh2.interests.all = true; else { foreach(string strInterest in this.interests) { if(strInterest == "URL") oqh2.interests.locations = true; else if(strInterest == "DN") oqh2.interests.descriptivenames = true; else if(strInterest == "MD") oqh2.interests.metadata = true; else if(strInterest == "COM") oqh2.interests.comments = true; else if(strInterest == "FS") oqh2.interests.partiallyavailableobjects = true; else if(strInterest.Length > 0) System.Diagnostics.Debug.WriteLine("unknown g2 interest: " + strInterest); } } oqh2.matches = matches; //if(this.ipepReturn != null && (Stats.Updated.Gnutella2.ultrapeer || (Stats.Updated.everIncoming && Stats.Updated.udpIncoming))) //we don't care about a "reliable" delivery; we just wanna conserve bandwidth; so instead of the line above, we have the one below if(this.ipepReturn != null) UDPSR.SendOutgoingPacket(oqh2, this.ipepReturn); else { if(this.fromUdp) System.Diagnostics.Debug.WriteLine("g2 oqh2 has no where to go"); else Sck.scks[root.sockNum].SendPacket(oqh2); } } } noLocalQHTMatch: //route/broadcast it wherever if(Stats.Updated.Gnutella2.ultrapeer) { //both hubs and leaves, or just leaves bool both = false; if(!fromUdp) { if(Sck.scks[root.sockNum].mode == G2Mode.Leaf) both = true; } else both = true; //do anything you haven't already done if(g2words == null && this.dn.Length > 0) g2words = Keywords.GetG2Keywords(ref dn); G2Word g2currentWord = g2words; while(g2currentWord != null) { if(g2currentWord.subwords == null && !g2currentWord.negative) g2currentWord.subwords = g2currentWord.word.Split(new char[] {' ', ','}, 15); g2currentWord = g2currentWord.next; } //begin foreach(Sck sck in Sck.scks) if(sck != null) if(sck.inQHT != null) if(both || sck.mode == G2Mode.Leaf) { bool matched = false; lock(Sck.scks[sck.sockNum]) { //query filtering if(urns != null) { URNinfo urniCurr = urns; while(urniCurr != null) { if(sck.inQHT[Hashing.Hash(ref urniCurr.fullurn, urniCurr.fullurn.Length, 20)] == false) { matched = true; break; } else urniCurr = urniCurr.next; } } if(!matched && g2words != null) { int found = 0, missing = 0; g2currentWord = g2words; while(g2currentWord != null) { if(!g2currentWord.negative) { if(g2currentWord.subwords == null) { if(sck.inQHT[Hashing.Hash(ref g2currentWord.word, g2currentWord.word.Length, 20)] == false) found++; else missing++; } else { for(int y = 0; y < g2currentWord.subwords.Length; y++) { if(sck.inQHT[Hashing.Hash(ref g2currentWord.subwords[y], g2currentWord.subwords[y].Length, 20)] == false) found++; else missing++; } } } g2currentWord = g2currentWord.next; } if(missing == 0) { if(found > 0) matched = true; else matched = false; } else { float perc = (float)found / (float)(found+missing); if(perc > 0.66) matched = true; else matched = false; } } } if(matched) { OCopy ocopy = new OCopy(); ocopy.payload = root.inPayload; ocopy.CreateHeader("Q2", root.be, root.cf); sck.SendPacket2(ocopy); } } } } /// <summary> /// Interests found in a query. /// If no interest packet is found, all is set to true. /// URN is to always be included, regardless of interests. /// </summary> public struct Interests { public bool all; public bool locations; public bool descriptivenames; public bool metadata; public bool comments; public bool partiallyavailableobjects; } public override Child ChildType(ref string name) { if(name == "UDP") return new UDP(); else if(name == "URN") return new URN(); else if(name == "DN") return new DescName(); else if(name == "MD") return new Metadata(); else if(name == "SZR") return new SizeRestriction(); else if(name == "I") return new Interest(); else return new UnknownChild(ref name); } public class UDP : Child { public override void Process(int offset, int len) { if(len == 10) { ((Query)root).ipepReturn = new IPEndPoint(Endian.GetIPAddress(root.inPayload, offset), Endian.ToUInt16(root.inPayload, offset+4, root.be)); ((Query)root).queryKey = Endian.ToInt32(root.inPayload, offset+6, root.be); } else if(len != 6) System.Diagnostics.Debug.WriteLine("Q2/UDP invalid len: " + len.ToString()); } } public class URN : Child { public override void Process(int offset, int len) { if(len > 12) { int nullLoc = Utils.FindNull(root.inPayload, offset, len); if(nullLoc == -1) { Utils.Diag("G2 Q2 URN nullLoc problem"); return; } string strUrn = Utils.GetString(root.inPayload, offset, nullLoc-offset); if(strUrn.Length == 11 && strUrn == "tree:tiger/" && len == 36) { URNinfo urni = ReturnNextURNinfo(); urni.fullurn = "urn:tree:tiger/:" + Base32.Encode(root.inPayload, offset+12, 24); urni.len = 24; urni.loc = offset+12; } else if(strUrn.Length == 3 && strUrn == "ttr" && len == 28) { URNinfo urni = ReturnNextURNinfo(); urni.fullurn = "urn:tree:tiger/:" + Base32.Encode(root.inPayload, offset+4, 24); urni.len = 24; urni.loc = offset+4; } else if(strUrn.Length == 4 && strUrn == "sha1" && len == 25) { URNinfo urni = ReturnNextURNinfo(); urni.fullurn = "urn:sha1:" + Base32.Encode(root.inPayload, offset+5, 20); urni.len = 20; urni.loc = offset+5; } else if(strUrn.Length == 8 && strUrn == "bitprint" && len == 53) { URNinfo urni = ReturnNextURNinfo(); urni.fullurn = "urn:sha1:" + Base32.Encode(root.inPayload, offset+9, 20); urni.len = 20; urni.loc = offset+9; urni.next = new URNinfo(); urni = urni.next; urni.fullurn = "urn:tree:tiger/:" + Base32.Encode(root.inPayload, offset+29, 24); urni.len = 24; urni.loc = offset+29; } else if(strUrn.Length == 2 && strUrn == "bp" && len == 47) { URNinfo urni = ReturnNextURNinfo(); urni.fullurn = "urn:sha1:" + Base32.Encode(root.inPayload, offset+3, 20); urni.len = 20; urni.loc = offset+3; urni.next = new URNinfo(); urni = urni.next; urni.fullurn = "urn:tree:tiger/:" + Base32.Encode(root.inPayload, offset+23, 24); urni.len = 24; urni.loc = offset+23; } else if(strUrn.Length == 3 && strUrn == "md5" && len == 20) { URNinfo urni = ReturnNextURNinfo(); urni.fullurn = "urn:md5:" + Base32.Encode(root.inPayload, offset+4, 16); urni.len = 16; urni.loc = offset+4; } else if(strUrn.Length == 4 && strUrn == "ed2k" && len == 21) { URNinfo urni = ReturnNextURNinfo(); urni.fullurn = "urn:ed2k:" + Base32.Encode(root.inPayload, offset+5, 16); urni.len = 16; urni.loc = offset+5; } } } URNinfo ReturnNextURNinfo() { if(((Query)root).urns == null) { ((Query)root).urns = new URNinfo(); return ((Query)root).urns; } else { URNinfo cur = ((Query)root).urns; while(cur.next != null) cur = cur.next; cur.next = new URNinfo(); return cur.next; } } } public class DescName : Child { public override void Process(int offset, int len) { if(len > 0) ((Query)this.root).dn = Utils.GetString(root.inPayload, offset, len); } } public class Metadata : Child { public override void Process(int offset, int len) { // } } public class SizeRestriction : Child { public override void Process(int offset, int len) { if(len == 8) { ((Query)root).minSize = Endian.ToUInt32(root.inPayload, offset, root.be); ((Query)root).maxSize = Endian.ToUInt32(root.inPayload, offset+4, root.be); ((Query)root).sizeRestrict = true; } else System.Diagnostics.Debug.WriteLine("we don't support g2 q2 SZR len of " + len.ToString()); } } public class Interest : Child { static char[] delims = new char[]{'\0'}; public override void Process(int offset, int len) { if(len > 0) ((Query)root).interests = Utils.GetString(root.inPayload, offset, len).Split(delims, 600); } } } public class QueryAck : Message { int timeStamp = 0; int retry = 0; IPAddress remoteHub; public override void Process(int offset, int len) { if(root.sockNum == -1) this.remoteHub = root.ipep.Address; else this.remoteHub = Sck.scks[root.sockNum].remoteIPA; if(len < 16) throw new Exception("QA packet didn't have guid"); GUIDitem gitem = new GUIDitem(root.inPayload, offset); //check if it's for us if(Search.activeSearches.Count > 0) { lock(Search.activeSearches) { foreach(Search search in Search.activeSearches) if(gitem.Equals(search.guid)) { Child child = this.children; while(child != null) { child.Read(child.offset); if(child.GetType() == typeof(DoneHub)) search.DoneHub(((DoneHub)child).ipa); child = child.nextChild; } if(this.retry > 0) HostCache.UpdateRetryTime(this.remoteHub, this.retry); return; } } } //if not for us... if(Stats.Updated.Gnutella2.ultrapeer) { Router.RouteEntry re; lock(Router.htRoutes) { if(Router.htRoutes.ContainsKey(gitem)) re = (Router.RouteEntry)Router.htRoutes[gitem];#if DEBUG else { Utils.Diag("G2 QA no route found"); return; }#else else return;#endif } //make a copy... but insert an FR child OCopy ocopy = new OCopy(); //make room for FR child ocopy.payload = new byte[root.inPayload.Length+(1+1+2+4)]; //copy all children... but skip the null byte and the guid for now int tmpIndex = root.inPayload.Length-(1+16); Array.Copy(root.inPayload, 0, ocopy.payload, 0, tmpIndex); //start the FR child OMessage.Setllen(ocopy.payload, tmpIndex, 1); OMessage.Setnlen(ocopy.payload, tmpIndex, 2); //the below code is compatible with both little endian and big endian if(root.be) ocopy.payload[tmpIndex] |= 0x02; tmpIndex++; Endian.VarBytesFromInt(ocopy.payload, tmpIndex, 4, 1); tmpIndex++; ocopy.payload[tmpIndex] = (byte)'F'; tmpIndex++; ocopy.payload[tmpIndex] = (byte)'R'; tmpIndex++; if(root.ipep != null) Array.Copy(Endian.GetBytes(root.ipep.Address), 0, ocopy.payload, tmpIndex, 4); else Array.Copy(Endian.GetBytes(Sck.scks[root.sockNum].remoteIPA), 0, ocopy.payload, tmpIndex, 4); tmpIndex += 4; //end of the FR child... null packet and guid follow Array.Copy(root.inPayload, root.inPayload.Length-(1+16), ocopy.payload, tmpIndex, (1+16)); ocopy.CreateHeader("FR", root.be, true); Router.RoutePacket(ocopy, re); } } public override Child ChildType(ref string name) { if(name == "D") return new DoneHub(); else if(name == "S") return new SearchHub(); else if(name == "TS")
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -